zoukankan      html  css  js  c++  java
  • Spring Boot 集成spring security4


    项目GitHub地址 :

    https://github.com/FrameReserve/TrainingBoot


    Spring Boot (三)集成spring security,标记地址:

    https://github.com/FrameReserve/TrainingBoot/releases/tag/0.0.3



    pom.xml

    只列举 Spring Security配置,完整配置请查看Git项目地址

    1. <properties>  
    2.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
    3.         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>  
    4.         <java.version>1.8</java.version>  
    5.         <!--  依赖版本  -->  
    6.         <mybatis.version>3.4.1</mybatis.version>  
    7.         <mybatis.spring.version>1.3.0</mybatis.spring.version>  
    8.           
    9.         <spring-security.version>4.1.0.RELEASE</spring-security.version>  
    10.     </properties>  
    11.   
    12.   
    13.   
    14. <!-- spring security -->  
    15.         <dependency>  
    16.             <groupId>org.springframework.security</groupId>  
    17.             <artifactId>spring-security-web</artifactId>  
    18.             <version>${spring-security.version}</version>  
    19.         </dependency>  
    20.         <dependency>  
    21.             <groupId>org.springframework.security</groupId>  
    22.             <artifactId>spring-security-config</artifactId>  
    23.             <version>${spring-security.version}</version>  
    24.         </dependency>  
    25.         <dependency>  
    26.             <groupId>org.springframework.security</groupId>  
    27.             <artifactId>spring-security-taglibs</artifactId>  
    28.             <version>${spring-security.version}</version>  
    29.         </dependency>  


    Spring Security 配置类:

    src/main/java/com/training/core/security/WebSecurityConfig.java

    1. package com.training.core.security;  
    2.   
    3. import java.util.ArrayList;  
    4. import java.util.List;  
    5.   
    6. import javax.annotation.Resource;  
    7.   
    8. import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;  
    9. import org.springframework.context.annotation.Bean;  
    10. import org.springframework.context.annotation.Configuration;  
    11. import org.springframework.security.access.AccessDecisionManager;  
    12. import org.springframework.security.access.AccessDecisionVoter;  
    13. import org.springframework.security.access.vote.AuthenticatedVoter;  
    14. import org.springframework.security.access.vote.RoleVoter;  
    15. import org.springframework.security.authentication.AuthenticationManager;  
    16. import org.springframework.security.authentication.event.LoggerListener;  
    17. import org.springframework.security.config.annotation.ObjectPostProcessor;  
    18. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;  
    19. import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;  
    20. import org.springframework.security.config.annotation.web.builders.HttpSecurity;  
    21. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;  
    22. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;  
    23. import org.springframework.security.core.userdetails.UserDetailsService;  
    24. import org.springframework.security.web.access.AccessDeniedHandler;  
    25. import org.springframework.security.web.access.AccessDeniedHandlerImpl;  
    26. import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;  
    27. import org.springframework.security.web.access.expression.WebExpressionVoter;  
    28. import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;  
    29. import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;  
    30. import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;  
    31. import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;  
    32. import org.springframework.security.web.util.matcher.AntPathRequestMatcher;  
    33.   
    34. import com.training.sysmanager.service.AclResourcesService;  
    35. import com.training.sysmanager.service.impl.AclResourcesServiceImpl;  
    36.   
    37. /** 
    38.  * Created by Athos on 2016-10-16. 
    39.  */  
    40. @Configuration  
    41. @EnableWebSecurity  
    42. @EnableGlobalMethodSecurity(prePostEnabled = true)  
    43. public class WebSecurityConfig extends WebSecurityConfigurerAdapter {  
    44.   
    45.     @Resource  
    46.     private UserDetailsService userDetailsService;  
    47.   
    48.     @Resource  
    49.     private MySecurityMetadataSource mySecurityMetadataSource;  
    50.   
    51.     @Override  
    52.     protected void configure(HttpSecurity http) throws Exception {  
    53.   
    54.         http.addFilterAfter(MyUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);  
    55.         // 开启默认登录页面  
    56.         http.authorizeRequests().anyRequest().authenticated().withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {  
    57.             public <O extends FilterSecurityInterceptor> O postProcess(O fsi) {  
    58.                 fsi.setSecurityMetadataSource(mySecurityMetadataSource);  
    59.                 fsi.setAccessDecisionManager(accessDecisionManager());  
    60.                 fsi.setAuthenticationManager(authenticationManagerBean());  
    61.                 return fsi;  
    62.             }  
    63.         }).and().exceptionHandling().authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login.html")).and().logout().logoutSuccessUrl("/index.html").permitAll();  
    64.         // 自定义accessDecisionManager访问控制器,并开启表达式语言  
    65.         http.exceptionHandling().accessDeniedHandler(accessDeniedHandler()).and().authorizeRequests().anyRequest().authenticated().expressionHandler(webSecurityExpressionHandler());  
    66.   
    67.         // 自定义登录页面  
    68.         http.csrf().disable();  
    69.   
    70.         // 自定义注销  
    71.         // http.logout().logoutUrl("/logout").logoutSuccessUrl("/login")  
    72.         // .invalidateHttpSession(true);  
    73.   
    74.         // session管理  
    75.         http.sessionManagement().maximumSessions(1);  
    76.   
    77.         // RemeberMe  
    78.         // http.rememberMe().key("webmvc#FD637E6D9C0F1A5A67082AF56CE32485");  
    79.   
    80.     }  
    81.   
    82.     @Override  
    83.     protected void configure(AuthenticationManagerBuilder auth) throws Exception {  
    84.         // 自定义UserDetailsService  
    85.         auth.userDetailsService(userDetailsService);  
    86.     }  
    87.   
    88.     @Bean  
    89.     UsernamePasswordAuthenticationFilter MyUsernamePasswordAuthenticationFilter() {  
    90.         UsernamePasswordAuthenticationFilter myUsernamePasswordAuthenticationFilter = new UsernamePasswordAuthenticationFilter();  
    91.         myUsernamePasswordAuthenticationFilter.setPostOnly(true);  
    92.         myUsernamePasswordAuthenticationFilter.setAuthenticationManager(authenticationManagerBean());  
    93.         myUsernamePasswordAuthenticationFilter.setUsernameParameter("name_key");  
    94.         myUsernamePasswordAuthenticationFilter.setPasswordParameter("pwd_key");  
    95.         myUsernamePasswordAuthenticationFilter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login""POST"));  
    96.         myUsernamePasswordAuthenticationFilter.setAuthenticationFailureHandler(simpleUrlAuthenticationFailureHandler());  
    97.         return myUsernamePasswordAuthenticationFilter;  
    98.     }  
    99.   
    100.     @Bean  
    101.     AccessDeniedHandler accessDeniedHandler() {  
    102.         AccessDeniedHandlerImpl accessDeniedHandler = new AccessDeniedHandlerImpl();  
    103.         accessDeniedHandler.setErrorPage("/securityException/accessDenied");  
    104.         return accessDeniedHandler;  
    105.     }  
    106.   
    107.     @Bean  
    108.     public LoggerListener loggerListener() {  
    109.         System.out.println("org.springframework.security.authentication.event.LoggerListener");  
    110.         return new LoggerListener();  
    111.     }  
    112.   
    113.     @Bean  
    114.     public org.springframework.security.access.event.LoggerListener eventLoggerListener() {  
    115.         System.out.println("org.springframework.security.access.event.LoggerListener");  
    116.         return new org.springframework.security.access.event.LoggerListener();  
    117.     }  
    118.   
    119.     /* 
    120.      *  
    121.      * 这里可以增加自定义的投票器 
    122.      */  
    123.     @Bean(name = "accessDecisionManager")  
    124.     public AccessDecisionManager accessDecisionManager() {  
    125.         List<AccessDecisionVoter<? extends Object>> decisionVoters = new ArrayList();  
    126.         decisionVoters.add(new RoleVoter());  
    127.         decisionVoters.add(new AuthenticatedVoter());  
    128.         decisionVoters.add(webExpressionVoter());// 启用表达式投票器  
    129.         MyAccessDecisionManager accessDecisionManager = new MyAccessDecisionManager(decisionVoters);  
    130.         return accessDecisionManager;  
    131.     }  
    132.   
    133.     @Bean(name = "authenticationManager")  
    134.     @Override  
    135.     public AuthenticationManager authenticationManagerBean() {  
    136.         AuthenticationManager authenticationManager = null;  
    137.         try {  
    138.             authenticationManager = super.authenticationManagerBean();  
    139.         } catch (Exception e) {  
    140.             e.printStackTrace();  
    141.         }  
    142.         return authenticationManager;  
    143.     }  
    144.   
    145.     @Bean(name = "failureHandler")  
    146.     public SimpleUrlAuthenticationFailureHandler simpleUrlAuthenticationFailureHandler() {  
    147.         return new SimpleUrlAuthenticationFailureHandler("/getLoginError");  
    148.     }  
    149.   
    150.     @Bean(name = "aclResourcesService")  
    151.     @ConditionalOnMissingBean  
    152.     public AclResourcesService aclResourcesService() {  
    153.         return new AclResourcesServiceImpl();  
    154.     }  
    155.   
    156.     /* 
    157.      * 表达式控制器 
    158.      */  
    159.     @Bean(name = "expressionHandler")  
    160.     public DefaultWebSecurityExpressionHandler webSecurityExpressionHandler() {  
    161.         DefaultWebSecurityExpressionHandler webSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();  
    162.         return webSecurityExpressionHandler;  
    163.     }  
    164.   
    165.     /* 
    166.      * 表达式投票器 
    167.      */  
    168.     @Bean(name = "expressionVoter")  
    169.     public WebExpressionVoter webExpressionVoter() {  
    170.         WebExpressionVoter webExpressionVoter = new WebExpressionVoter();  
    171.         webExpressionVoter.setExpressionHandler(webSecurityExpressionHandler());  
    172.         return webExpressionVoter;  
    173.     }  
    174.   
    175. }  


    自定义 UserDetailsService 用户、角色、资源获取类:

    src/main/java/com/training/core/security/UserDetailsServiceImpl.java

    1. package com.training.core.security;  
    2.   
    3. import java.util.ArrayList;  
    4. import java.util.List;  
    5.   
    6. import javax.annotation.Resource;  
    7.   
    8. import org.springframework.security.core.GrantedAuthority;  
    9. import org.springframework.security.core.authority.SimpleGrantedAuthority;  
    10. import org.springframework.security.core.userdetails.User;  
    11. import org.springframework.security.core.userdetails.UserDetails;  
    12. import org.springframework.security.core.userdetails.UserDetailsService;  
    13. import org.springframework.security.core.userdetails.UsernameNotFoundException;  
    14. import org.springframework.stereotype.Service;  
    15.   
    16. import com.training.sysmanager.entity.AclResources;  
    17. import com.training.sysmanager.entity.AclUser;  
    18. import com.training.sysmanager.service.AclResourcesService;  
    19. import com.training.sysmanager.service.AclRoleResourcesService;  
    20. import com.training.sysmanager.service.AclUserService;  
    21.   
    22. /** 
    23.  * Created by Athos on 2016-10-16. 
    24.  */  
    25. @Service("userDetailsService")  
    26. public class UserDetailsServiceImpl  implements UserDetailsService {  
    27.       
    28.     @Resource  
    29.     private AclUserService aclUserService;  
    30.     @Resource  
    31.     private AclRoleResourcesService aclRoleResourcesService;  
    32.     @Resource  
    33.     private AclResourcesService aclResourcesService;  
    34.   
    35.     /* (non-Javadoc) 
    36.      * @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String) 
    37.      */  
    38.     @Override  
    39.     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {  
    40.         List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();  
    41.         AclUser aclUser = aclUserService.findAclUserByName(username);  
    42.         String resourceIds = aclRoleResourcesService.selectResourceIdsByRoleIds(aclUser.getRoleIds());  
    43.         List<AclResources> aclResourcesList = aclResourcesService.selectAclResourcesByResourceIds(resourceIds);  
    44.         for (AclResources aclResources : aclResourcesList) {  
    45.             auths.add(new SimpleGrantedAuthority(aclResources.getAuthority().toUpperCase()));  
    46.         }  
    47. //        auths.addAll(aclResourcesList.stream().map(resources -> new SimpleGrantedAuthority(resources.getAuthority().toUpperCase())).collect(Collectors.toList()));  
    48.         return new User(aclUser.getUserName().toLowerCase(),aclUser.getUserPwd().toLowerCase(),true,true,true,true,auths);  
    49.     }  
    50. }  


自定义securityMetadataSource:

src/main/java/com/training/core/security/MySecurityMetadataSource.java

  1. package com.training.core.security;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Collection;  
  5. import java.util.HashMap;  
  6. import java.util.Iterator;  
  7. import java.util.List;  
  8. import java.util.Map;  
  9.   
  10. import javax.servlet.http.HttpServletRequest;  
  11.   
  12. import org.springframework.security.access.ConfigAttribute;  
  13. import org.springframework.security.access.SecurityConfig;  
  14. import org.springframework.security.web.FilterInvocation;  
  15. import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;  
  16. import org.springframework.security.web.util.matcher.AntPathRequestMatcher;  
  17. import org.springframework.security.web.util.matcher.RequestMatcher;  
  18. import org.springframework.stereotype.Component;  
  19.   
  20. import com.training.sysmanager.entity.AclResources;  
  21. import com.training.sysmanager.service.AclResourcesService;  
  22.   
  23. /** 
  24.  * Created by Athos on 2016-10-16. 
  25.  */  
  26. @Component("mySecurityMetadataSource")  
  27. public class MySecurityMetadataSource  implements FilterInvocationSecurityMetadataSource {  
  28.   
  29.     private static Map<String,Collection<ConfigAttribute>> aclResourceMap = null;  
  30.     private AclResourcesService aclResourcesService;  
  31.   
  32.     /** 
  33.      * 构造方法 
  34.      */  
  35.     //1  
  36.     public MySecurityMetadataSource(AclResourcesService aclResourcesService){  
  37.         this.aclResourcesService=aclResourcesService;  
  38.         loadResourceDefine();  
  39.     }  
  40.   
  41.     @Override  
  42.     public Collection<ConfigAttribute> getAttributes(Object object)throws IllegalArgumentException{  
  43.         HttpServletRequest request=((FilterInvocation)object).getRequest();  
  44.         Iterator<String> ite = aclResourceMap.keySet().iterator();  
  45.         while (ite.hasNext()){  
  46.             String resURL = ite.next();  
  47.             RequestMatcher requestMatcher = new AntPathRequestMatcher(resURL);  
  48.             if(requestMatcher.matches(request)){  
  49.                 return aclResourceMap.get(resURL);  
  50.             }  
  51.         }  
  52.         return null;  
  53.     }  
  54.     //4  
  55.     @Override  
  56.     public Collection<ConfigAttribute> getAllConfigAttributes() {  
  57.         System.out.println("metadata : getAllConfigAttributes");  
  58.         return null;  
  59.     }  
  60.     //3  
  61.     @Override  
  62.     public boolean supports(Class<?> clazz) {  
  63.         System.out.println("metadata : supports");  
  64.         return true;  
  65.     }  
  66.   
  67.   
  68.     private void loadResourceDefine(){  
  69.         /** 
  70.          * 因为只有权限控制的资源才需要被拦截验证,所以只加载有权限控制的资源 
  71.          */  
  72.         List<AclResources> aclResourceses = aclResourcesService.selectAclResourcesTypeOfRequest();  
  73.         aclResourceMap = new HashMap<>();  
  74.         for (AclResources aclResources:aclResourceses){  
  75.             ConfigAttribute ca = new SecurityConfig(aclResources.getAuthority().toUpperCase());  
  76.             String url = aclResources.getUrl();  
  77.             if(aclResourceMap.containsKey(url)){  
  78.                 Collection<ConfigAttribute> value = aclResourceMap.get(url);  
  79.                 value.add(ca);  
  80.                 aclResourceMap.put(url,value);  
  81.   
  82.             }else {  
  83.                 Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();  
  84.                 atts.add(ca);  
  85.                 aclResourceMap.put(url,atts);  
  86.             }  
  87.         }  
  88.     }  
  89. }  


自定义AbstractAccessDecisionManager权限决策类,

src/main/java/com/training/core/security/MyAccessDecisionManager.java

  1. package com.training.core.security;  
  2.   
  3. import org.springframework.security.access.AccessDecisionVoter;  
  4. import org.springframework.security.access.AccessDeniedException;  
  5. import org.springframework.security.access.ConfigAttribute;  
  6. import org.springframework.security.access.vote.AbstractAccessDecisionManager;  
  7. import org.springframework.security.authentication.InsufficientAuthenticationException;  
  8. import org.springframework.security.core.Authentication;  
  9. import org.springframework.security.core.GrantedAuthority;  
  10.   
  11. import java.util.Collection;  
  12. import java.util.Iterator;  
  13. import java.util.List;  
  14.   
  15. /** 
  16.  * Created by Athos on 2016-10-16. 
  17.  */  
  18.   
  19. public class MyAccessDecisionManager  extends AbstractAccessDecisionManager {  
  20.     protected MyAccessDecisionManager(List<AccessDecisionVoter<? extends Object>> decisionVoters) {  
  21.         super(decisionVoters);  
  22.     }  
  23.   
  24.     @Override  
  25.     public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {  
  26.         if(configAttributes==null){  
  27.             return;  
  28.         }  
  29.         Iterator<ConfigAttribute> ite = configAttributes.iterator();  
  30.         while(ite.hasNext()){  
  31.             ConfigAttribute ca = ite.next();  
  32.             String needRole = (ca).getAttribute();  
  33.             for (GrantedAuthority ga : authentication.getAuthorities()){  
  34.                 if (needRole.equals(ga.getAuthority())){  
  35.                     return;  
  36.                 }  
  37.             }  
  38.         }  
  39.         throw new AccessDeniedException("没有权限,拒绝访问!");  
  40.     }  
  41.     @Override  
  42.     public boolean supports(ConfigAttribute attribute) {  
  43.         return false;  
  44.     }  
  45.   
  46.     /** 
  47.      * Iterates through all <code>AccessDecisionVoter</code>s and ensures each can support 
  48.      * the presented class. 
  49.      * <p> 
  50.      * If one or more voters cannot support the presented class, <code>false</code> is 
  51.      * returned. 
  52.      * 
  53.      * @param clazz the type of secured object being presented 
  54.      * @return true if this type is supported 
  55.      */  
  56.     @Override  
  57.     public boolean supports(Class<?> clazz) {  
  58.         return true;  
  59.     }  
  60. }  


用户、角色、资源(菜单)略。

详情请看GIT完成工程。

https://github.com/FrameReserve/TrainingBoot

        </div>
查看全文
  • 相关阅读:
    解决Oracle XE报错ORA-12516(oracle回话数超出限制)
    端口被占用如何处理
    ORACLE initialization or shutdown in progress 错误解决办法
    oracle的闪回功能
    Linux入门
    oracle字段like多个条件
    navicat常用快捷键与SQL基本使用
    Oracle四舍五入,向上取整,向下取整
    无限循环小数化分数
    筛选素数
  • 原文地址:https://www.cnblogs.com/jpfss/p/9050176.html
  • Copyright © 2011-2022 走看看