关于Boot应用中集成Spring Security你必须了解的那些事
<h4>Spring Security</h4>
Spring Security是Spring社区的一个顶级项目,也是Spring Boot官方推荐使用的Security框架。除了常规的Authentication和Authorization之外,Spring Security还提供了诸如ACLs,LDAP,JAAS,CAS等高级特性以满足复杂场景下的安全需求。虽然功能强大,Spring Security的配置并不算复杂(得益于官方详尽的文档),尤其在3.2版本加入Java Configuration的支持之后,可以彻底告别令不少初学者望而却步的XML Configuration。在使用层面,Spring Security提供了多种方式进行业务集成,包括注解,Servlet API,JSP Tag,系统API等。下面就结合一些示例代码介绍Boot应用中集成Spring Security的几个关键点。
1 核心概念
Principle(User), Authority(Role)和Permission是Spring Security的3个核心概念。跟通常理解上Role和Permission之间一对多的关系不同,在Spring Security中,Authority和Permission是两个完全独立的概念,两者并没有必然的联系,但可以通过配置进行关联。
2 基础配置
首先在项目的pom.xml中引入spring-boot-starter-security依赖。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>
和其余Spring框架一样,XML Configuration和Java Configuration是Spring Security的两种常用配置方式。Spring 3.2版本之后,Java Configuration因其流式API支持,强类型校验等特性,逐渐替代XML Configuration成为更广泛的配置方式。下面是一个示例Java Configuration。
@Configuration@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled = true)public class SecurityConfig extends WebSecurityConfigurerAdapter {@AutowiredMyUserDetailsService detailsService;@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().and().formLogin().loginPage("/login").permitAll().defaultSuccessUrl("/", true).and().logout().logoutUrl("/logout").and().sessionManagement().maximumSessions(1).expiredUrl("/expired").and().and().exceptionHandling().accessDeniedPage("/accessDenied");}@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers("/js/**", "/css/**", "/images/**", "/**/favicon.ico");}@Overridepublic void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(detailsService).passwordEncoder(new BCryptPasswordEncoder());}}
- @EnableWebSecurity: 禁用Boot的默认Security配置,配合@Configuration启用自定义配置(需要扩展WebSecurityConfigurerAdapter)
- @EnableGlobalMethodSecurity(prePostEnabled = true): 启用Security注解,例如最常用的@PreAuthorize
- configure(HttpSecurity): Request层面的配置,对应XML Configuration中的
<http>元素 - configure(WebSecurity): Web层面的配置,一般用来配置无需安全检查的路径
- configure(AuthenticationManagerBuilder): 身份验证配置,用于注入自定义身份验证Bean和密码校验规则
3 扩展配置
完成基础配置之后,下一步就是实现自己的UserDetailsService和PermissionEvaluator,分别用于自定义Principle, Authority和Permission。
@Componentpublic class MyUserDetailsService implements UserDetailsService {@Autowiredprivate LoginService loginService;@Autowiredprivate RoleService roleService;@Overridepublic UserDetails loadUserByUsername(String username) {if (StringUtils.isBlank(username)) {throw new UsernameNotFoundException("用户名为空");}Login login = loginService.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException("用户不存在"));Set<GrantedAuthority> authorities = new HashSet<>();roleService.getRoles(login.getId()).forEach(r -> authorities.add(new SimpleGrantedAuthority(r.getName())));return new org.springframework.security.core.userdetails.User(username, login.getPassword(),true,//是否可用true,//是否过期true,//证书不过期为truetrue,//账户未锁定为trueauthorities);}}
创建GrantedAuthority对象时,一般名称加上ROLE_前缀。
@Componentpublic class MyPermissionEvaluator implements PermissionEvaluator {@Autowiredprivate LoginService loginService;@Autowiredprivate RoleService roleService;@Overridepublic boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {String username = authentication.getName();Login login = loginService.findByUsername(username).get();return roleService.authorized(login.getId(), targetDomainObject.toString(), permission.toString());}@Overridepublic boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {// not supportedreturn false;}}
- hasPermission(Authentication, Object, Object)和hasPermission(Authentication, Serializable, String, Object)两个方法分别对应Spring Security中两个同名的表达式。
4 业务集成
Spring Security提供了注解,Servlet API,JSP Tag,系统API等多种方式进行集成,最常用的是第一种方式,包含@Secured, @PreAuthorize, @PreFilter, @PostAuthorize和@PostFilter五个注解。@Secure是最初版本中的一个注解,自3.0版本引入了支持Spring EL表达式的其余四个注解之后,就很少使用了。
@RequestMapping(value = "/hello", method = RequestMethod.GET)@PreAuthorize("authenticated and hasPermission('hello', 'view')")public String hello(Model model) {String username = SecurityContextHolder.getContext().getAuthentication().getName();model.addAttribute("message", username);return "hello";}
- @PreAuthorize("authenticated and hasPermission('hello', 'view')"): 表示只有当前已登录的并且拥有("hello", "view")权限的用户才能访问此页面
- SecurityContextHolder.getContext().getAuthentication().getName(): 获取当前登录的用户,也可以通过HttpServletRequest.getRemoteUser()获取
总结
以上就是Spring Security的一般集成步骤,更多细节和高级特性可参考官方文档。
参考
- http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/
- http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/
http://emacoo.cn/blog/spring-boot-security
</div>
关于Boot应用中集成Spring Security你必须了解的那些事的更多相关文章
- 【Spring】关于Boot应用中集成Spring Security你必须了解的那些事
Spring Security Spring Security是Spring社区的一个顶级项目,也是Spring Boot官方推荐使用的Security框架.除了常规的Authentication和A ...
- Spring Boot中集成Spring Security 专题
check to see if spring security is applied that the appropriate resources are permitted: @Configurat ...
- spring boot rest 接口集成 spring security(2) - JWT配置
Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...
- spring boot rest 接口集成 spring security(1) - 最简配置
Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...
- spring-boot-starter-security Spring Boot中集成Spring Security
spring security是springboot支持的权限控制系统. security.basic.authorize-mode 要使用权限控制模式. security.basic.enabled ...
- SpringBoot 集成Spring security
Spring security作为一种安全框架,使用简单,能够很轻松的集成到springboot项目中,下面讲一下如何在SpringBoot中集成Spring Security.使用gradle项目管 ...
- SpringBoot集成Spring Security
1.Spring Security介绍 Spring security,是一个强大的和高度可定制的身份验证和访问控制框架.它是确保基于Spring的应用程序的标准 --来自官方参考手册 Spring ...
- Spring Boot中使用 Spring Security 构建权限系统
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配置的Bean,为应用系统提供声明式的安全 ...
- Spring Boot 集成 Spring Security 实现权限认证模块
作者:王帅@CodeSheep 写在前面 关于 Spring Security Web系统的认证和权限模块也算是一个系统的基础设施了,几乎任何的互联网服务都会涉及到这方面的要求.在Java EE领 ...
随机推荐
- 洛谷 1164 小A点菜
题目背景 uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家……餐馆,很低端的那种. uim指着墙上的价目表(太低级了没有菜单),说:“随便点”. 题目描述 不过uim由于买了一些辅(e ...
- 迅为4412开发板Linux设备树的镜像烧写和源码简单优化教程
1 烧写: 烧写和4412默认镜像的烧写类似,使用fastboot. 先更新uboot,用4412默认uboot更新支持设备树的uboot 用支持设备树的uboot烧写. 进入支持设备树的uboo ...
- shell 复合条件测试 if [ $1 == "1" -o $1 == "0" ] ------==和-eq怎么用
想要实现: ”,或者$1等于“” ];then 输出一些东西 ”,或者$1等于“” ];then 输出一些东西 fi 这里比较难操作的是等于和或者: 等于: -eq 或者 == 或者: -o 见: ...
- CAD交互绘制圆形批注(网页版)
js中实现代码说明: 动态拖放时的绘制事件: function DoDynWorldDrawFun(dX,dY,pWorldDraw,pData) { //自定义实体的GUID标识符 var sGui ...
- blog.yiz96.com
欢迎访问我的新博客 blog.yiz96.com
- 洛谷 P2668 斗地主
毒瘤题目,搞了三天-- 也没什么好讲的,就是纯搜索,先搜顺子,再搜其他的,最后单张牌和对子的时候,就不要搜索了,直接枚举,不然会T飞掉多么痛的领悟-- 主要还是靠码力 #include<iost ...
- 新建Maven工程,pom.xml报错web.xml is missing and <failOnMissingWebXml> is set to true
错误原因: 项目中没有web.xml 解决办法: 在项目中添加web.xml 在pom.xml中添加下面的插件 <build> <plugins> <plugin> ...
- Linux 永久修改主机名hostname
前言: 由于最近用3台机器,经常切换导致有容易区别的需求. 故想修改主机名. 实验环境:Ubuntu 17 教程: 1. 使用hostname 命令先临时修改 sudo hostname your_n ...
- Java8特性详解 lambda表达式 Stream【转】
本文转自http://www.cnblogs.com/aoeiuv/p/5911692.html 1.lambda表达式 Java8最值得学习的特性就是Lambda表达式和Stream API,如果有 ...
- 离线功能对比:service worker和applicationCache
SW 复杂,事件驱动,可以拦截请求,和缓存这些请求的响应数据,实现的效果更加灵活 AppCache 简单易用,声明式的将要缓存的文件清单声明在一个文件中.由于设计上的原因,它存在一些问题,导致难以运用 ...