zoukankan      html  css  js  c++  java
  • Spring Security3详细配置

    Spring Security3详细配置

    表名:RESOURCE 解释:资源表
    备注: 资源表

    RESOURCE(资源表)

    是否主键

    字段名

    字段描述

    数据类型

    长度

    可空

    约束

    缺省值

    备注

    ID

    id

    INT(11)

    11

    TYPE

    类型(URL,METHOD)

    VARCHAR(50)

    50

    VALUE

    URL

    VARCHAR(50)

    50

    MODEL_NAME

    模块名

    VARCHAR(50)

    50

    PARENT_ID

    父模块ID

    VARCHAR(50)

    50

     


    表名:ROLE 解释:角色表
    备注: 角色表

    ROLE(角色表)

    是否主键

    字段名

    字段描述

    数据类型

    长度

    可空

    约束

    缺省值

    备注

    ID

    id

    INT(11)

    11

    NAME

    角色名

    VARCHAR(50)

    50

    DESCRIPTION

    角色描述

    VARCHAR(50)

    50

     


    表名:ROLE_RESOURCE 解释:角色资源表
    备注: 角色资源表

    ROLE_RESOURCE(角色资源表)

    是否主键

    字段名

    字段描述

    数据类型

    长度

    可空

    约束

    缺省值

    备注

    ROLE_ID

    角色ID

    VARCHAR(50)

    50

    RESOURCE_ID

    资源ID

    VARCHAR(50)

    50

     


    表名:USER 解释:用户表
    备注: 用户表

    USER(用户表)

    是否主键

    字段名

    字段描述

    数据类型

    长度

    可空

    约束

    缺省值

    备注

    NAME

    用户名

    VARCHAR(50)

    50

    PASSWORD

    密码

    VARCHAR(50)

    50

    DISABLED

    是否有效

    CHAR(1)

    1

    EMAIL

    邮箱

    VARCHAR(100)

    100

     


    表名:USER_ROLE 解释:用户角色表
    备注: 用户角色表

    USER_ROLE(用户角色表)

    是否主键

    字段名

    字段描述

    数据类型

    长度

    可空

    约束

    缺省值

    备注

    USER_ID

    用户ID

    VARCHAR(50)

    50

    ROLE_ID

    角色ID

    VARCHAR(50)

    50

    相关的jar包可到spring官网下载,我使用的是spring security 3.1.3

    首先web.xml配置

    1. <context-param>  
    2. <param-name>contextConfigLocation</param-name>  
    3. <param-value>  
    4. classpath:/config/*.xml   
    5. </param-value>  
    6. </context-param>  
    7. <!-- spring监听 -->  
    8. <listener>  
    9. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    10. </listener>  
    11. <!-- Spring Security会话控制 -->  
    12. <listener>  
    13. <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>  
    14. </listener>  
    15. <!-- Spring security Filter -->  
    16. <filter>  
    17. <filter-name>springSecurityFilterChain</filter-name>  
    18. <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
    19. </filter>  
    20. <filter-mapping>  
    21. <filter-name>springSecurityFilterChain</filter-name>  
    22. <url-pattern>/*</url-pattern>  
    23. </filter-mapping>  


    这里主要做了三件事,

    1、加载Spring;

    2、加载Spring Security;

    3、添加Spring Security Session监听器(用于控制登录)

    Spring Secirty如下:

    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <beans:beans xmlns="http://www.springframework.org/schema/security"  
    3. xmlns:beans="http://www.springframework.org/schema/beans"  
    4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
    6. http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">  
    7. <debug/>  
    8. <global-method-security  pre-post-annotations="enabled" />  
    9. <!-- 此目录下不需要过滤 -->  
    10. <http pattern="/js/**" security="none"/>  
    11. <http pattern="/resources/**" security="none"/>  
    12. <http pattern="/css/**" security="none"/>  
    13. <http pattern="/dwr/**" security="none"/>  
    14. <http pattern="/images/**" security="none"/>  
    15. <http pattern="/login.jsp" security="none"/>  
    16. <http use-expressions="true">  
    17. <!-- 非匿名用户就允许访问 -->  
    18. <intercept-url pattern="/index.jsp" access="isAuthenticated()"/>  
    19. <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=true"  always-use-default-target="true" default-target-url="/index.jsp" />  
    20. <logout logout-success-url="/login.jsp"/>  
    21. <!-- 没有权限访问的页面 -->  
    22. <access-denied-handler error-page="/403.jsp"/>  
    23. <session-management></session-management>  
    24. <remember-me/>  
    25. <custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR"/>  
    26. </http>  
    27. <!-- 指定提示信息 -->  
    28. <beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">  
    29. <beans:property name="basename" value="classpath:spring-security"></beans:property>  
    30. </beans:bean>  
    31. <authentication-manager alias="myAuthenticationManager">  
    32. <authentication-provider ref="authenticationProvider">  
    33. </authentication-provider>  
    34. </authentication-manager>  
    35. <beans:bean id="authenticationProvider"   
    36. class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">  
    37. <beans:property name="userDetailsService" ref="userdetailService" />  
    38. <!--显示用户错误信息-->  
    39. <beans:property name="hideUserNotFoundExceptions" value="false" />  
    40. <beans:property  name="passwordEncoder" ref="md5password"></beans:property >  
    41. </beans:bean>  
    42. <!-- 密码加密策略 -->  
    43. <beans:bean name="md5password" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"></beans:bean>  
    44. <beans:bean name="userdetailService" class="com.yindejin.system.MyAuthenticationManager">  
    45. <beans:property name="systemService" ref="systemService"></beans:property>  
    46. </beans:bean>  
    47. <beans:bean name="myFilter" class="com.yindejin.system.MySecurityFilter">  
    48. <!-- 用户拥有的权限 -->    
    49. <beans:property name="authenticationManager" ref="myAuthenticationManager" />    
    50. <!-- 用户是否拥有所请求资源的权限 -->    
    51. <beans:property name="accessDecisionManager" ref="myAccessDecisionManager" />    
    52. <!-- 资源与权限对应关系 -->    
    53. <beans:property name="securityMetadataSource" ref="mySecurityMetadataSource" />  
    54. </beans:bean>  
    55. <beans:bean id="myAccessDecisionManager" class="com.yindejin.system.MyAccessDecisionManager"></beans:bean>    
    56. <beans:bean id="mySecurityMetadataSource" class="com.yindejin.system.MySecurityMetadataSource">    
    57. <beans:constructor-arg name="systemService" ref="systemService"></beans:constructor-arg>    
    58. </beans:bean>    
    59. </beans:beans>  

    <custom-filter ref="myFilter" before="FILTER_SECURITY_INTERCEPTOR"/>

    这里的FILTER_SECURITY_INTERCEPTOR是Spring Security过滤器链中默认的Filter,

    他的主要功能是

    1、校验用户名、密码;

    2、初始化时一次性加载所有的资源角色信息

    3、检查用户访问权限

    我们自定义的Filter必须在它之前,由于我们自己的过滤器和默认过滤器功能是一样的,所以就替换掉了原来的过滤器。

    接下来是myFilter几个关键类


     


    MySecurityFilter

    1. package com.yindejin.system;  
    2. import java.io.IOException;  
    3. import javax.servlet.Filter;  
    4. import javax.servlet.FilterChain;  
    5. import javax.servlet.FilterConfig;  
    6. import javax.servlet.ServletException;  
    7. import javax.servlet.ServletRequest;  
    8. import javax.servlet.ServletResponse;  
    9. import org.springframework.security.access.SecurityMetadataSource;  
    10. import org.springframework.security.access.intercept.AbstractSecurityInterceptor;  
    11. import org.springframework.security.access.intercept.InterceptorStatusToken;  
    12. import org.springframework.security.web.FilterInvocation;  
    13. import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;  
    14. public class MySecurityFilter extends AbstractSecurityInterceptor implements Filter {  
    15. //与applicationContext-security.xml里的myFilter的属性securityMetadataSource对应,  
    16. //其他的两个组件,已经在AbstractSecurityInterceptor定义  
    17. private FilterInvocationSecurityMetadataSource securityMetadataSource;  
    18. @Override  
    19. public SecurityMetadataSource obtainSecurityMetadataSource() {  
    20. return this.securityMetadataSource;  
    21. }  
    22. public void doFilter(ServletRequest request, ServletResponse response,  
    23. FilterChain chain) throws IOException, ServletException {  
    24. FilterInvocation fi = new FilterInvocation(request, response, chain);  
    25. invoke(fi);  
    26. }  
    27. private void invoke(FilterInvocation fi) throws IOException, ServletException {  
    28. System.out.println("用户发送请求! ");  
    29. InterceptorStatusToken token = null;  
    30. token = super.beforeInvocation(fi);  
    31. try {  
    32. fi.getChain().doFilter(fi.getRequest(), fi.getResponse());  
    33. } finally {  
    34. super.afterInvocation(token, null);  
    35. }  
    36. }  
    37. public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {  
    38. return securityMetadataSource;  
    39. }  
    40. public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource) {  
    41. this.securityMetadataSource = securityMetadataSource;  
    42. }  
    43. public void init(FilterConfig arg0) throws ServletException {  
    44. // TODO Auto-generated method stub  
    45. }  
    46. public void destroy() {  
    47. // TODO Auto-generated method stub  
    48. }  
    49. @Override  
    50. public Class<? extends Object> getSecureObjectClass() {  
    51. //下面的MyAccessDecisionManager的supports方面必须放回true,否则会提醒类型错误  
    52. return FilterInvocation.class;  
    53. }}  


     

    MySecurityMetadataSource

    1. package com.yindejin.system;  
    2. import java.util.ArrayList;  
    3. import java.util.Collection;  
    4. import java.util.HashMap;  
    5. import java.util.LinkedHashMap;  
    6. import java.util.List;  
    7. import java.util.Map;  
    8. import java.util.Set;  
    9. import javax.servlet.http.HttpServletRequest;  
    10. import org.springframework.security.access.ConfigAttribute;  
    11. import org.springframework.security.access.SecurityConfig;  
    12. import org.springframework.security.web.FilterInvocation;  
    13. import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;  
    14. import org.springframework.security.web.util.AntPathRequestMatcher;  
    15. import org.springframework.security.web.util.RequestMatcher;  
    16. import com.yindejin.system.service.ISystemService;  
    17. import com.yindejin.vo.Resource;  
    18. import com.yindejin.vo.Role;  
    19. import com.yindejin.vo.User;  
    20. //1 加载资源与权限的对应关系  
    21. public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource {  
    22. //由spring调用  
    23. public MySecurityMetadataSource(ISystemService systemService) {  
    24. this.systemService = systemService;  
    25. }  
    26. private ISystemService systemService;  
    27. public ISystemService getSystemService() {  
    28. return systemService;  
    29. }  
    30. public void setSystemService(ISystemService systemService) {  
    31. this.systemService = systemService;  
    32. }  
    33. private static LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> resourceMap = null;  
    34. public Collection<ConfigAttribute> getAllConfigAttributes() {  
    35. // TODO Auto-generated method stub  
    36. return null;  
    37. }  
    38. public boolean supports(Class<?> clazz) {  
    39. // TODO Auto-generated method stub  
    40. return true;  
    41. }  
    42. //加载所有资源与权限的关系  
    43. private Map<String, String> getResource() {  
    44. Map<String, String> resourceMap = new HashMap<String, String>();  
    45. List<User> users = systemService.getAllUser();  
    46. for(User user:users){     
    47. for(Role role : user.getUserRoles()) {  
    48. Set<Resource> resources = role.getRoleResources();  
    49. for(Resource resource : resources) {  
    50. String url = resource.getValue();  
    51. if(!resourceMap.containsKey(url)) {  
    52. resourceMap.put(url, role.getName());  
    53. }else{  
    54. String roleName = resourceMap.get(url);  
    55. resourceMap.put(url, roleName+","+role.getName());  
    56. }  
    57. }  
    58. }  
    59. }  
    60. return resourceMap;  
    61. }  
    62. private void loadResourceDefine(){  
    63. resourceMap = new LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>>();  
    64. Map<String, String> resource = getResource();  
    65. for(Map.Entry<String, String> entry:resource.entrySet()){  
    66. Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();  
    67. configAttributes.add(new SecurityConfig(entry.getValue()));  
    68. resourceMap.put(new AntPathRequestMatcher(entry.getKey()), configAttributes);  
    69. }  
    70. }  
    71. //返回所请求资源所需要的权限  
    72. public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {  
    73. HttpServletRequest request = ((FilterInvocation) object).getRequest();  
    74. if(null==resourceMap){  
    75. System.out.println("请求地址 " + ((FilterInvocation) object).getRequestUrl());  
    76. loadResourceDefine();  
    77. System.out.println("我需要的认证:"+resourceMap.toString());  
    78. }  
    79. for (Map.Entry<RequestMatcher, Collection<ConfigAttribute>> entry : resourceMap.entrySet()) {  
    80. if (entry.getKey().matches(request)) {  
    81. return entry.getValue();  
    82. }  
    83. }  
    84. return null;  
    85. }  
    86. }  


    MyAccessDecisionManager

    1. package com.yindejin.system;  
    2. import java.util.Collection;  
    3. import java.util.Iterator;  
    4. import org.springframework.security.access.AccessDecisionManager;  
    5. import org.springframework.security.access.AccessDeniedException;  
    6. import org.springframework.security.access.ConfigAttribute;  
    7. import org.springframework.security.authentication.InsufficientAuthenticationException;  
    8. import org.springframework.security.core.Authentication;  
    9. import org.springframework.security.core.GrantedAuthority;  
    10. //3  
    11. public class MyAccessDecisionManager implements AccessDecisionManager {  
    12. public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {  
    13. if(configAttributes == null) {  
    14. return;  
    15. }  
    16. //所请求的资源拥有的权限(一个资源对多个权限)  
    17. Iterator<ConfigAttribute> iterator = configAttributes.iterator();  
    18. while(iterator.hasNext()) {  
    19. ConfigAttribute configAttribute = iterator.next();  
    20. //访问所请求资源所需要的权限  
    21. String needPermission = configAttribute.getAttribute();  
    22. System.out.println("needPermission is " + needPermission);  
    23. //用户所拥有的权限authentication  
    24. for(GrantedAuthority ga : authentication.getAuthorities()) {  
    25. if(needPermission.contains((ga.getAuthority()))) {  
    26. return;  
    27. }  
    28. }  
    29. }  
    30. //没有权限让我们去捕捉  
    31. throw new AccessDeniedException(" 没有权限访问!");  
    32. }  
    33. public boolean supports(ConfigAttribute attribute) {  
    34. // TODO Auto-generated method stub  
    35. return true;  
    36. }  
    37. public boolean supports(Class<?> clazz) {  
    38. // TODO Auto-generated method stub  
    39. return true;  
    40. }  
    41. }  


     

    MyAuthenticationManager

    1. package com.yindejin.system;  
    2. import org.springframework.security.core.userdetails.UserDetails;  
    3. import org.springframework.security.core.userdetails.UserDetailsService;  
    4. import org.springframework.security.core.userdetails.UsernameNotFoundException;  
    5. import com.yindejin.system.service.ISystemService;  
    6. import com.yindejin.util.StringUtils;  
    7. import com.yindejin.vo.User;  
    8. public class MyAuthenticationManager implements UserDetailsService {  
    9. private ISystemService systemService;  
    10. public void setSystemService(ISystemService systemService) {  
    11. this.systemService = systemService;  
    12. }  
    13. @Override  
    14. public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {  
    15. if(!StringUtils.isEmpty(userName)){  
    16. throw new UsernameNotFoundException("用户名不能为空!");  
    17. }  
    18. User user = systemService.loginByUserName(userName);  
    19. if (user == null) {  
    20. throw new UsernameNotFoundException("用户名或密码错误!");  
    21. }  
    22. return user;  
    23. }  
    24. }  

    User

    1. package com.yindejin.vo;  
    2. import java.util.ArrayList;  
    3. import java.util.Collection;  
    4. import java.util.HashMap;  
    5. import java.util.HashSet;  
    6. import java.util.List;  
    7. import java.util.Map;  
    8. import java.util.Set;  
    9. import javax.persistence.Transient;  
    10. import org.springframework.security.core.GrantedAuthority;  
    11. import org.springframework.security.core.authority.GrantedAuthorityImpl;  
    12. import org.springframework.security.core.userdetails.UserDetails;  
    13. /** 
    14. * User entity. @author MyEclipse Persistence Tools 
    15. */  
    16. public class User implements UserDetails {  
    17. // Fields  
    18. private Integer id;  
    19. private String name;  
    20. private String password = "123456";  
    21. private Integer disabled = 0;  
    22. private String email;  
    23. public String getEmail() {  
    24. return email;  
    25. }  
    26. public void setEmail(String email) {  
    27. this.email = email;  
    28. }  
    29. private Set<Role> userRoles = new HashSet<Role>();  
    30. @Transient  
    31. private Map<String, List<Resource>> roleResources;  
    32. // Constructors  
    33. public Integer getId() {  
    34. return id;  
    35. }  
    36. public void setId(Integer id) {  
    37. this.id = id;  
    38. }  
    39. public String getName() {  
    40. return name;  
    41. }  
    42. public void setName(String name) {  
    43. this.name = name;  
    44. }  
    45. public String getPassword() {  
    46. return password;  
    47. }  
    48. public void setPassword(String password) {  
    49. this.password = password;  
    50. }  
    51. public Integer getDisabled() {  
    52. return disabled;  
    53. }  
    54. public void setDisabled(Integer disabled) {  
    55. this.disabled = disabled;  
    56. }  
    57. public Set<Role> getUserRoles() {  
    58. return userRoles;  
    59. }  
    60. public void setUserRoles(Set<Role> userRoles) {  
    61. this.userRoles = userRoles;  
    62. }  
    63. /** default constructor */  
    64. public User() {  
    65. }  
    66. public String getUsername() {  
    67. return name;  
    68. }  
    69. public boolean isAccountNonExpired() {  
    70. return true;  
    71. }  
    72. public boolean isAccountNonLocked() {  
    73. return true;  
    74. }  
    75. public boolean isCredentialsNonExpired() {  
    76. return true;  
    77. }  
    78. public boolean isEnabled() {  
    79. return this.disabled==0?true:false;  
    80. }  
    81. /** 
    82. * @return the roleResources 
    83. */  
    84. public Map<String, List<Resource>> getRoleResources() {  
    85. // init roleResources for the first time  
    86. if(this.roleResources == null) {              
    87. this.roleResources = new HashMap<String, List<Resource>>();  
    88. for(Role role : this.userRoles) {  
    89. String roleName = role.getName();  
    90. Set<Resource> resources = role.getRoleResources();  
    91. for(Resource resource : resources) {  
    92. String key = roleName + "_" + resource.getType();  
    93. if(!this.roleResources.containsKey(key)) {  
    94. this.roleResources.put(key, new ArrayList<Resource>());  
    95. }  
    96. this.roleResources.get(key).add(resource);                    
    97. }  
    98. }  
    99. }  
    100. return this.roleResources;  
    101. }  
    102. @SuppressWarnings("deprecation")  
    103. @Override  
    104. public Collection<GrantedAuthority> getAuthorities() {  
    105. Set<GrantedAuthority> authSet = new HashSet<GrantedAuthority>();  
    106. for(Role role : getUserRoles()){  
    107. authSet.add(new GrantedAuthorityImpl(role.getName()));  
    108. }  
    109. return authSet;  
    110. }  
    111. }  


     

  • 相关阅读:
    Median Value
    237. Delete Node in a Linked List
    206. Reverse Linked List
    160. Intersection of Two Linked Lists
    83. Remove Duplicates from Sorted List
    21. Merge Two Sorted Lists
    477. Total Hamming Distance
    421. Maximum XOR of Two Numbers in an Array
    397. Integer Replacement
    318. Maximum Product of Word Lengths
  • 原文地址:https://www.cnblogs.com/fan-yuan/p/6249064.html
Copyright © 2011-2022 走看看