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. }  


     

  • 相关阅读:
    SpringBoot(三)——使用Thymeleaf模板
    “Usage of API documented as @since 1.8+”报错的解决办法
    JAVA的多态性
    SQL的JOIN语句
    共享锁和排他锁
    软件工程团队作业---项目选题报告
    结对作业
    PMS---团队展示
    第二次作业——个人项目实战
    第一次作业---准备
  • 原文地址:https://www.cnblogs.com/fan-yuan/p/6249064.html
Copyright © 2011-2022 走看看