项目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项目地址

<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><!--  依赖版本  --><mybatis.version>3.4.1</mybatis.version><mybatis.spring.version>1.3.0</mybatis.spring.version><spring-security.version>4.1.0.RELEASE</spring-security.version></properties><!-- spring security --><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-web</artifactId><version>${spring-security.version}</version></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId><version>${spring-security.version}</version></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-taglibs</artifactId><version>${spring-security.version}</version></dependency>

Spring Security 配置类:

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

package com.training.core.security;import java.util.ArrayList;
import java.util.List;import javax.annotation.Resource;import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.vote.AuthenticatedVoter;
import org.springframework.security.access.vote.RoleVoter;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.event.LoggerListener;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.access.AccessDeniedHandlerImpl;
import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
import org.springframework.security.web.access.expression.WebExpressionVoter;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;import com.training.sysmanager.service.AclResourcesService;
import com.training.sysmanager.service.impl.AclResourcesServiceImpl;/*** Created by Athos on 2016-10-16.*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Resourceprivate UserDetailsService userDetailsService;@Resourceprivate MySecurityMetadataSource mySecurityMetadataSource;@Overrideprotected void configure(HttpSecurity http) throws Exception {http.addFilterAfter(MyUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);// 开启默认登录页面http.authorizeRequests().anyRequest().authenticated().withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {public <O extends FilterSecurityInterceptor> O postProcess(O fsi) {fsi.setSecurityMetadataSource(mySecurityMetadataSource);fsi.setAccessDecisionManager(accessDecisionManager());fsi.setAuthenticationManager(authenticationManagerBean());return fsi;}}).and().exceptionHandling().authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login.html")).and().logout().logoutSuccessUrl("/index.html").permitAll();// 自定义accessDecisionManager访问控制器,并开启表达式语言http.exceptionHandling().accessDeniedHandler(accessDeniedHandler()).and().authorizeRequests().anyRequest().authenticated().expressionHandler(webSecurityExpressionHandler());// 自定义登录页面http.csrf().disable();// 自定义注销// http.logout().logoutUrl("/logout").logoutSuccessUrl("/login")// .invalidateHttpSession(true);// session管理http.sessionManagement().maximumSessions(1);// RemeberMe// http.rememberMe().key("webmvc#FD637E6D9C0F1A5A67082AF56CE32485");}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {// 自定义UserDetailsServiceauth.userDetailsService(userDetailsService);}@BeanUsernamePasswordAuthenticationFilter MyUsernamePasswordAuthenticationFilter() {UsernamePasswordAuthenticationFilter myUsernamePasswordAuthenticationFilter = new UsernamePasswordAuthenticationFilter();myUsernamePasswordAuthenticationFilter.setPostOnly(true);myUsernamePasswordAuthenticationFilter.setAuthenticationManager(authenticationManagerBean());myUsernamePasswordAuthenticationFilter.setUsernameParameter("name_key");myUsernamePasswordAuthenticationFilter.setPasswordParameter("pwd_key");myUsernamePasswordAuthenticationFilter.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login", "POST"));myUsernamePasswordAuthenticationFilter.setAuthenticationFailureHandler(simpleUrlAuthenticationFailureHandler());return myUsernamePasswordAuthenticationFilter;}@BeanAccessDeniedHandler accessDeniedHandler() {AccessDeniedHandlerImpl accessDeniedHandler = new AccessDeniedHandlerImpl();accessDeniedHandler.setErrorPage("/securityException/accessDenied");return accessDeniedHandler;}@Beanpublic LoggerListener loggerListener() {System.out.println("org.springframework.security.authentication.event.LoggerListener");return new LoggerListener();}@Beanpublic org.springframework.security.access.event.LoggerListener eventLoggerListener() {System.out.println("org.springframework.security.access.event.LoggerListener");return new org.springframework.security.access.event.LoggerListener();}/** * 这里可以增加自定义的投票器*/@Bean(name = "accessDecisionManager")public AccessDecisionManager accessDecisionManager() {List<AccessDecisionVoter<? extends Object>> decisionVoters = new ArrayList();decisionVoters.add(new RoleVoter());decisionVoters.add(new AuthenticatedVoter());decisionVoters.add(webExpressionVoter());// 启用表达式投票器MyAccessDecisionManager accessDecisionManager = new MyAccessDecisionManager(decisionVoters);return accessDecisionManager;}@Bean(name = "authenticationManager")@Overridepublic AuthenticationManager authenticationManagerBean() {AuthenticationManager authenticationManager = null;try {authenticationManager = super.authenticationManagerBean();} catch (Exception e) {e.printStackTrace();}return authenticationManager;}@Bean(name = "failureHandler")public SimpleUrlAuthenticationFailureHandler simpleUrlAuthenticationFailureHandler() {return new SimpleUrlAuthenticationFailureHandler("/getLoginError");}@Bean(name = "aclResourcesService")@ConditionalOnMissingBeanpublic AclResourcesService aclResourcesService() {return new AclResourcesServiceImpl();}/** 表达式控制器*/@Bean(name = "expressionHandler")public DefaultWebSecurityExpressionHandler webSecurityExpressionHandler() {DefaultWebSecurityExpressionHandler webSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();return webSecurityExpressionHandler;}/** 表达式投票器*/@Bean(name = "expressionVoter")public WebExpressionVoter webExpressionVoter() {WebExpressionVoter webExpressionVoter = new WebExpressionVoter();webExpressionVoter.setExpressionHandler(webSecurityExpressionHandler());return webExpressionVoter;}}

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

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

package com.training.core.security;import java.util.ArrayList;
import java.util.List;import javax.annotation.Resource;import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;import com.training.sysmanager.entity.AclResources;
import com.training.sysmanager.entity.AclUser;
import com.training.sysmanager.service.AclResourcesService;
import com.training.sysmanager.service.AclRoleResourcesService;
import com.training.sysmanager.service.AclUserService;/*** Created by Athos on 2016-10-16.*/
@Service("userDetailsService")
public class UserDetailsServiceImpl  implements UserDetailsService {@Resourceprivate AclUserService aclUserService;@Resourceprivate AclRoleResourcesService aclRoleResourcesService;@Resourceprivate AclResourcesService aclResourcesService;/* (non-Javadoc)* @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)*/@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();AclUser aclUser = aclUserService.findAclUserByName(username);String resourceIds = aclRoleResourcesService.selectResourceIdsByRoleIds(aclUser.getRoleIds());List<AclResources> aclResourcesList = aclResourcesService.selectAclResourcesByResourceIds(resourceIds);for (AclResources aclResources : aclResourcesList) {auths.add(new SimpleGrantedAuthority(aclResources.getAuthority().toUpperCase()));}
//        auths.addAll(aclResourcesList.stream().map(resources -> new SimpleGrantedAuthority(resources.getAuthority().toUpperCase())).collect(Collectors.toList()));return new User(aclUser.getUserName().toLowerCase(),aclUser.getUserPwd().toLowerCase(),true,true,true,true,auths);}
}

自定义securityMetadataSource:

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

package com.training.core.security;import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.stereotype.Component;import com.training.sysmanager.entity.AclResources;
import com.training.sysmanager.service.AclResourcesService;/*** Created by Athos on 2016-10-16.*/
@Component("mySecurityMetadataSource")
public class MySecurityMetadataSource  implements FilterInvocationSecurityMetadataSource {private static Map<String,Collection<ConfigAttribute>> aclResourceMap = null;private AclResourcesService aclResourcesService;/*** 构造方法*///1public MySecurityMetadataSource(AclResourcesService aclResourcesService){this.aclResourcesService=aclResourcesService;loadResourceDefine();}@Overridepublic Collection<ConfigAttribute> getAttributes(Object object)throws IllegalArgumentException{HttpServletRequest request=((FilterInvocation)object).getRequest();Iterator<String> ite = aclResourceMap.keySet().iterator();while (ite.hasNext()){String resURL = ite.next();RequestMatcher requestMatcher = new AntPathRequestMatcher(resURL);if(requestMatcher.matches(request)){return aclResourceMap.get(resURL);}}return null;}//4@Overridepublic Collection<ConfigAttribute> getAllConfigAttributes() {System.out.println("metadata : getAllConfigAttributes");return null;}//3@Overridepublic boolean supports(Class<?> clazz) {System.out.println("metadata : supports");return true;}private void loadResourceDefine(){/*** 因为只有权限控制的资源才需要被拦截验证,所以只加载有权限控制的资源*/List<AclResources> aclResourceses = aclResourcesService.selectAclResourcesTypeOfRequest();aclResourceMap = new HashMap<>();for (AclResources aclResources:aclResourceses){ConfigAttribute ca = new SecurityConfig(aclResources.getAuthority().toUpperCase());String url = aclResources.getUrl();if(aclResourceMap.containsKey(url)){Collection<ConfigAttribute> value = aclResourceMap.get(url);value.add(ca);aclResourceMap.put(url,value);}else {Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();atts.add(ca);aclResourceMap.put(url,atts);}}}
}

自定义AbstractAccessDecisionManager权限决策类,

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

package com.training.core.security;import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.vote.AbstractAccessDecisionManager;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;import java.util.Collection;
import java.util.Iterator;
import java.util.List;/*** Created by Athos on 2016-10-16.*/public class MyAccessDecisionManager  extends AbstractAccessDecisionManager {protected MyAccessDecisionManager(List<AccessDecisionVoter<? extends Object>> decisionVoters) {super(decisionVoters);}@Overridepublic void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {if(configAttributes==null){return;}Iterator<ConfigAttribute> ite = configAttributes.iterator();while(ite.hasNext()){ConfigAttribute ca = ite.next();String needRole = (ca).getAttribute();for (GrantedAuthority ga : authentication.getAuthorities()){if (needRole.equals(ga.getAuthority())){return;}}}throw new AccessDeniedException("没有权限,拒绝访问!");}@Overridepublic boolean supports(ConfigAttribute attribute) {return false;}/*** Iterates through all <code>AccessDecisionVoter</code>s and ensures each can support* the presented class.* <p>* If one or more voters cannot support the presented class, <code>false</code> is* returned.** @param clazz the type of secured object being presented* @return true if this type is supported*/@Overridepublic boolean supports(Class<?> clazz) {return true;}
}

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

详情请看GIT完成工程。

https://github.com/FrameReserve/TrainingBoot

Spring Boot (三)集成spring security相关推荐

  1. spring boot(三) 集成mybatis

    前言 还记得之前我们写接口也是基于SpringMVC+MyBatis环境下,项目入手就需要N个配置文件,N个步骤才能实现,不但繁琐,而且时间长了xml配置文件太多,难以维护.现在基于spring bo ...

  2. (转)Spring Boot(三):Spring Boot 中 Redis 的使用

    http://www.ityouknow.com/springboot/2016/03/06/spring-boot-redis.html Spring Boot 对常用的数据库支持外,对 Nosql ...

  3. 【Spring Boot组件集成实战】集成Kaptcha谷歌验证码

    更多精彩内容,请访问 Spring Boot组件集成实战专栏 ! 推荐项目:一套基于Spring Boot+Layui的内容管理系统/快速开发脚手架(含完整的开发文档.演示网址等) 文章目录 1. 验 ...

  4. Spring Boot 工程集成全局唯一ID生成器 Vesta

    2019独角兽企业重金招聘Python工程师标准>>> 本文内容脑图如下: 文章共 760字,阅读大约需要 2分钟 ! 概 述 在前一篇文章 <Spring Boot工程集成全 ...

  5. Spring Boot + Shiro 集成

    2019独角兽企业重金招聘Python工程师标准>>> Spring Boot + Shiro 集成 Shiro 是一个流行的 Java 安全框架. 其实 Spring 有一个 Sp ...

  6. Spring Boot实践 | 利用Spring Security快速搞定权限控制

    目录 开始之前 快速开始 使用内存签名服务 使用数据库签名服务 使用自定义签名服务 限制请求 强制使用HTTPS 防止跨站点伪造请求 用户认证功能 在java web工程中,一般使用Servlet过滤 ...

  7. Spring Boot日志集成

    Spring Boot日志框架 Spring Boot支持Java Util Logging,Log4j2,Lockback作为日志框架,如果你使用starters启动器,Spring Boot将使用 ...

  8. 在spring boot中集成Swagger

    Swagger 在spring boot中集成Swagger 新建一个swagger项目 maven依赖 <!-- https://mvnrepository.com/artifact/io.s ...

  9. Spring Boot 快速集成第三方登录功能

    Spring Boot 快速集成第三方登录功能 前言 此 demo 主要演示 Spring Boot 项目如何使用 史上最全的第三方登录工具 - JustAuth 实现第三方登录,包括 QQ 登录.G ...

  10. Spring/Spring boot正确集成Quartz及解决@Autowired失效问题

    Spring/Spring boot正确集成Quartz及解决@Autowired失效问题 参考文章: (1)Spring/Spring boot正确集成Quartz及解决@Autowired失效问题 ...

最新文章

  1. linux nohup 英文全称 no hang up(
  2. Functional Options
  3. Python3 绘制同心圆代码示例
  4. 2020年全国普通高校毕业生874万,同比增加40万人。我们该何去何从?
  5. 第二十一章流 5 多种打开文件的方式 文件存在,文件不存在
  6. 吴恩达教授机器学习课程笔记【四】- 生成学习算法(1)高斯判别分析模型
  7. linux不解压情况下查看压缩包内文件的总行数、文件列表的数目
  8. iocomp iPlot使用说明6 轴属性设置
  9. 二叉树的层次遍历算法
  10. Ueditor基本用法-kityformula-上传图片-手写公式myscript
  11. 微信小程序--自定义按钮样式(1)
  12. 解决跳转ICP备案网页报400的问题
  13. linux常用命令课堂总结
  14. 《生物化学与分子生物学》----酶促反应动力学----听课笔记(九)
  15. C++实现积分函数(第一章)
  16. Android性能优化的5种方案
  17. 一个非常好的资源网站
  18. 红日安全 ATT&CK VulnStack靶场(三)
  19. 做网站时域名应该怎么选择
  20. iOS9 3DTouch开发 知识点详解

热门文章

  1. 关于C语言里面struct的相关知识
  2. 把object强制转换成int
  3. google dapper论文
  4. 为什么cpu要一心二用:浅谈多线程编程的一个具体例子
  5. 你了解设计公司的服务内容有哪些吗?
  6. 网络安全运维人员面临的痛点分析
  7. 区块链当前的发展现状
  8. 3.4利用单臂路由实现vlan间路由
  9. Android Menu菜单栏
  10. redis设计与实现-数据库篇