(二)spring.mvc spring security3
1<http pattern="/static/css/**" security="none" />
用来配置不需要ss拦截的url
2 <http use-expressions="true" entry-point-ref="authenticationProcessingFilterEntryPoint"
access-denied-page="/error/403.jsp">
这个可以代替默认的login,自己实现登陆验证,并且做一些自己爱做的事,比如保存一些信息到session等
3 <custom-filter ref="loginFilter" position="FORM_LOGIN_FILTER" />
自定义登陆filter
4 <!--login filter begin-->
<beans:bean id="loginFilter" class="com.cn.sh.framework.security.MyUsernamePasswordAuthenticationFilter">
MyUsernamePasswordAuthenticationFilter是验证用户名和密码的自我实现,目前demo没有实现登陆验证码功能
1 package com.cn.sh.framework.security; 2 3 import javax.servlet.http.HttpServletRequest; 4 import javax.servlet.http.HttpServletResponse; 5 import javax.servlet.http.HttpSession; 6 7 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.security.authentication.AuthenticationServiceException; 9 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 10 import org.springframework.security.core.Authentication; 11 import org.springframework.security.core.AuthenticationException; 12 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 13 14 import com.cn.sh.framework.util.MyWebsiteResource; 15 import com.cn.sh.mywebsite.auth.dao.UserDao; 16 import com.cn.sh.mywebsite.auth.domain.MyUser; 17 18 public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter { 19 20 public static final String VALIDATE_CODE = "validateCode"; 21 public static final String USERNAME = "j_username"; 22 public static final String PASSWORD = "j_password"; 23 24 @Autowired 25 private UserDao usersDao; 26 27 28 @Override 29 public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { 30 if (!request.getMethod().equals("POST")) { 31 throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); 32 } 33 // 0 TODO 检测验证码部分 34 //checkValidateCode(request); 35 36 // 1 get parameter(name,password) 37 String username = obtainUsername(request); 38 String password = obtainPassword(request); 39 40 System.out.println("username="+username + " " + "password="+password); 41 42 //验证用户账号与密码是否对应 43 username = username.trim(); 44 45 // 2 get user entity 46 MyUser users = this.usersDao.getUserByName(username); 47 48 //3 error or set user entity to session 49 if (users == null || !users.getPassword().equals(password)) { 50 request.getSession().setAttribute("msg", MyWebsiteResource.CURRENT_USER_NAMEORPASSWORD_ERROR); 51 throw new AuthenticationServiceException("用户名或者密码错误!"); 52 } else { 53 request.getSession().setAttribute(MyWebsiteResource.CURRENT_USER_INFO, users); 54 } 55 56 System.out.println("user is not null"); 57 58 //4 set detail 59 UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); 60 setDetails(request, authRequest); 61 62 return this.getAuthenticationManager().authenticate(authRequest); 63 } 64 65 protected void checkValidateCode(HttpServletRequest request) { 66 67 // HttpSession session = request.getSession(); 68 69 // String sessionValidateCode = obtainSessionValidateCode(session); 70 // //让上一次的验证码失效 71 // session.setAttribute(VALIDATE_CODE, null); 72 // String validateCodeParameter = obtainValidateCodeParameter(request); 73 // if (StringUtil.isEmpty(validateCodeParameter) 74 // || !sessionValidateCode.equalsIgnoreCase(validateCodeParameter)) { 75 // throw new AuthenticationServiceException("验证码错误!"); 76 // } 77 } 78 79 // private String obtainValidateCodeParameter(HttpServletRequest request) { 80 // Object obj = request.getParameter(VALIDATE_CODE); 81 // return null == obj ? "" : obj.toString(); 82 // } 83 84 protected String obtainSessionValidateCode(HttpSession session) { 85 Object obj = session.getAttribute(VALIDATE_CODE); 86 return null == obj ? "" : obj.toString(); 87 } 88 89 @Override 90 protected String obtainUsername(HttpServletRequest request) { 91 Object obj = request.getParameter(USERNAME); 92 return null == obj ? "" : obj.toString(); 93 } 94 95 @Override 96 protected String obtainPassword(HttpServletRequest request) { 97 Object obj = request.getParameter(PASSWORD); 98 return null == obj ? "" : obj.toString(); 99 } 100 }
<beans:property name="filterProcessesUrl" value="/j_spring_security_check"></beans:property>
<beans:property name="authenticationSuccessHandler" ref="loginLogAuthenticationSuccessHandler"></beans:property>
<beans:property name="authenticationFailureHandler" ref="simpleUrlAuthenticationFailureHandler"></beans:property>
<beans:property name="authenticationManager" ref="myAuthenticationManager"></beans:property>
</beans:bean>
<beans:bean id="loginLogAuthenticationSuccessHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/auth/index.do"></beans:property>
登陆成功后的action
</beans:bean>
<beans:bean id="simpleUrlAuthenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/default.jsp"></beans:property>
default.jsp设计web-inf外的文件,它会重定向到web-inf内部,这个应该都明白什么意思。
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <html> 5 <head> 6 </head> 7 <body> 8 <% 9 response.sendRedirect(request.getContextPath() + "/auth/prelogin.do"); 10 %> 11 </body> 12 </html>
</beans:bean>
<beans:bean id="authenticationProcessingFilterEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/auth/login.do" />
<beans:property name="forceHttps" value="false" />
</beans:bean>
<!--login filter end-->
<custom-filter ref="filterSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR" />
这个是根据数据数据验证登陆用户的角色和url权限
<beans:bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor" autowire="byType">
<beans:property name="authenticationManager" ref="myAuthenticationManager" />
<beans:property name="accessDecisionManager" ref="myAccessDecisionManager" />
<beans:property name="securityMetadataSource" ref="filterInvocationSecurityMetadataSource" />
</beans:bean>
<beans:bean id="filterInvocationSecurityMetadataSource" class="com.cn.sh.framework.security.JdbcFilterInvocationDefinitionSourceFactoryBean">
1 package com.cn.sh.framework.security; 2 3 import java.util.Collection; 4 import java.util.LinkedHashMap; 5 import java.util.List; 6 import java.util.Map; 7 8 import com.cn.sh.framework.resource.ResourceMapping; 9 import com.cn.sh.mywebsite.res.domain.*; 10 import org.springframework.beans.factory.FactoryBean; 11 import org.springframework.jdbc.core.support.JdbcDaoSupport; 12 import org.springframework.security.access.ConfigAttribute; 13 import org.springframework.security.access.ConfigAttributeEditor; 14 import org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource; 15 import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; 16 import org.springframework.security.web.util.AntPathRequestMatcher; 17 import org.springframework.security.web.util.RequestMatcher; 18 19 public class JdbcFilterInvocationDefinitionSourceFactoryBean extends JdbcDaoSupport implements FactoryBean { 20 21 private String resourceQuery; 22 23 public boolean isSingleton() { 24 return true; 25 } 26 27 public Class getObjectType() { 28 return FilterInvocationSecurityMetadataSource.class; 29 } 30 31 public Object getObject() { 32 return new DefaultFilterInvocationSecurityMetadataSource(this.buildRequestMap()); 33 } 34 35 protected Map<String, String> findResources() { 36 37 // get resources from DB 38 ResourceMapping resourceMapping = new ResourceMapping(getDataSource(), resourceQuery); 39 40 Map<String, String> resourceMap = new LinkedHashMap<String, String>(); 41 42 // format resources 43 for (Resource resource : (List<Resource>) resourceMapping.execute()) { 44 45 String url = resource.getUrl(); 46 String role = resource.getRole(); 47 48 if (resourceMap.containsKey(url)) { 49 String value = resourceMap.get(url); 50 resourceMap.put(url, value + "," + role); 51 } else { 52 resourceMap.put(url, role); 53 } 54 } 55 56 return resourceMap; 57 } 58 59 protected LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> buildRequestMap() { 60 61 LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap = null; 62 requestMap = new LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>>(); 63 64 ConfigAttributeEditor editor = new ConfigAttributeEditor(); 65 66 // get resource 67 Map<String, String> resourceMap = this.findResources(); 68 69 for (Map.Entry<String, String> entry : resourceMap.entrySet()) { 70 71 String key = entry.getKey(); 72 73 editor.setAsText(entry.getValue()); 74 //System.out.println(key + "|" + entry.getValue() + "|"+ editor.getAsText()); 75 76 AntPathRequestMatcher obj = new AntPathRequestMatcher(key); 77 78 Collection<ConfigAttribute> c = (Collection<ConfigAttribute>) editor.getValue(); 79 80 requestMap.put(obj, c); 81 } 82 83 return requestMap; 84 } 85 86 public void setResourceQuery(String resourceQuery) { 87 this.resourceQuery = resourceQuery; 88 } 89 }
<beans:property name="dataSource" ref="dataSource"/>
数据库地址
<beans:property name="resourceQuery" value="select re.res_string,r.name from role r join resc_role rr on r.id=rr.role_id join resc re on re.id=rr.resc_id order by re.priority,res_string"/>
角色权限关系sql
</beans:bean>
<authentication-manager alias="myAuthenticationManager">
<authentication-provider user-service-ref="myUserDetailServiceImpl"/>
构造UserDetails信息
1 package com.cn.sh.framework.security; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 import java.util.HashSet; 6 import java.util.List; 7 import java.util.Set; 8 9 import org.springframework.beans.factory.annotation.Autowired; 10 import org.springframework.security.core.GrantedAuthority; 11 import org.springframework.security.core.authority.GrantedAuthorityImpl; 12 import org.springframework.security.core.userdetails.User; 13 import org.springframework.security.core.userdetails.UserDetails; 14 import org.springframework.security.core.userdetails.UserDetailsService; 15 import org.springframework.security.core.userdetails.UsernameNotFoundException; 16 17 import com.cn.sh.mywebsite.auth.dao.UserDao; 18 import com.cn.sh.mywebsite.auth.domain.MyUser; 19 import com.cn.sh.mywebsite.authority.dao.AuthorityDao; 20 import com.cn.sh.mywebsite.res.domain.Resource; 21 import com.cn.sh.mywebsite.role.domain.Roles; 22 23 @SuppressWarnings("deprecation") 24 public class MyUserDetailServiceImpl implements UserDetailsService { 25 26 @Autowired 27 private UserDao usersDao; 28 @Autowired 29 private AuthorityDao aAuthorityDao ; 30 31 //登录验证 32 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 33 34 MyUser users = this.usersDao.getUserByName(username); 35 36 Collection<GrantedAuthority> grantedAuths = obtionGrantedAuthorities(users); 37 System.out.println("username is " + username + "|" + grantedAuths.size()); 38 39 boolean enables = true; 40 boolean accountNonExpired = true; 41 boolean credentialsNonExpired = true; 42 boolean accountNonLocked = true; 43 44 User userdetail = new User(users.getUsername(), users.getPassword(), 45 enables, accountNonExpired, credentialsNonExpired, 46 accountNonLocked, grantedAuths); 47 48 return userdetail; 49 } 50 51 private Set<GrantedAuthority> obtionGrantedAuthorities(MyUser user) { 52 Set<GrantedAuthority> authSet = new HashSet<GrantedAuthority>(); 53 List<Resource> resources = new ArrayList<Resource>(); 54 Set<Roles> roles = aAuthorityDao.getAuthoritiesByUserId(user.getId()); 55 56 if (roles != null) { 57 System.out.println("user.getId()="+user.getId() + "roles.size="+roles.size()); 58 for (Roles role : roles) { 59 Set<Resource> tempRes = aAuthorityDao.getResoucesByRoleId(role.getId()); 60 61 if (tempRes != null){ 62 System.out.println("tempRes.size="+tempRes.size()); 63 for (Resource res : tempRes) { 64 //System.out.println(res.getName() + "|" + res.getId() + "|" + res.getRole() + "|" + res.getUrl()); 65 resources.add(res); 66 } 67 } 68 } 69 70 for (Resource res : resources) { 71 authSet.add(new GrantedAuthorityImpl(res.getRole())); 72 } 73 } 74 75 return authSet; 76 } 77 }
</authentication-manager>
<beans:bean id="myAccessDecisionManager" class="com.cn.sh.framework.security.MyAccessDecisionManager"/>
验证url需要的角色权限和登陆者是否满足
1 package com.cn.sh.framework.security; 2 3 import java.util.Collection; 4 import java.util.Iterator; 5 import org.springframework.security.access.AccessDecisionManager; 6 import org.springframework.security.access.AccessDeniedException; 7 import org.springframework.security.access.ConfigAttribute; 8 import org.springframework.security.authentication.InsufficientAuthenticationException; 9 import org.springframework.security.core.Authentication; 10 import org.springframework.security.core.GrantedAuthority; 11 12 public class MyAccessDecisionManager implements AccessDecisionManager { 13 14 public void decide(Authentication authentication, Object url, Collection<ConfigAttribute> configAttributes) 15 throws AccessDeniedException, InsufficientAuthenticationException { 16 17 if(url!=null){ 18 System.out.println("url="+url); 19 } 20 21 if(configAttributes == null) { 22 System.out.println("configAttributes == null"); 23 return; 24 } 25 26 Iterator<ConfigAttribute> iterator = configAttributes.iterator(); 27 28 while(iterator.hasNext()) { 29 ConfigAttribute configAttribute = iterator.next(); 30 String needPermission = configAttribute.getAttribute(); 31 //System.out.println("needPermission is " + needPermission + " Authorities="+authentication.getAuthorities().size()); 32 for(GrantedAuthority ga : authentication.getAuthorities()) { 33 //System.out.println("ga.getAuthority="+ga.getAuthority()); 34 if(needPermission.equals(ga.getAuthority())) { 35 //System.out.println("needPermission==ga.getAuthority"); 36 return; 37 } 38 } 39 } 40 41 System.out.println("没有权限访问"); 42 throw new AccessDeniedException(" 没有权限访问!"); 43 } 44 45 public boolean supports(ConfigAttribute arg0) { 46 return true; 47 } 48 49 public boolean supports(Class<?> arg0) { 50 return true; 51 } 52 }
<beans:bean id="myUserDetailServiceImpl" class="com.cn.sh.framework.security.MyUserDetailServiceImpl"/>
新手分享学习经验,希望老鸟多多指点。
没有源码下载,自己摸索进步快。