SpringSecurity简介:
 
权限管理中的相关概念
主体 principal:
使用系统的用户或设备或从其他系统远程登录的用户等等,简单说就是谁使用系统谁就是主体。
认证 authentication:
权限管理系统确认一个主体的身份,允许主体进入系统。简单说就是“主体”证明自己是谁。
授权 authorization:
将操作系统的“权力”“授予”“主体”,这样主体就具备了操作系统中特定功能的能力。 所以简单来说,授权就是给用户分配权限。
 
SpringSecurity本质是过滤器链:
  客户端发起一个请求,在请求到达Controller前Security通过一系列的过滤处理,完成对用户的认证授权等相关处理。需要注意的是在传统业务系统开发中,我们一般会在UserController中实现一个login接口来处理用户登录,但在使用Security时不需要在Controller实现login接口,它帮助我们在过滤器中实现了用户密码登录。默认通过UsernamePasswordAuthenticationFilter过滤器实现,从表单中读取用户名密码进行认证登录。
  1. org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter
    org.springframework.security.web.context.SecurityContextPersistenceFilter
    org.springframework.security.web.header.HeaderWriterFilter
    org.springframework.security.web.csrf.CsrfFilter
    org.springframework.security.web.authentication.logout.LogoutFilter
    org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
    org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter
    org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter
    org.springframework.security.web.savedrequest.RequestCacheAwareFilter
    org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter
    org.springframework.security.web.authentication.AnonymousAuthenticationFilter
    org.springframework.security.web.session.SessionManagementFilter
    org.springframework.security.web.access.ExceptionTranslationFilter
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor
 
主要过滤器
ExceptionTranslationFilter:异常处理过滤器,凡是在过滤器环节出现的错误都或转到该过滤器进行统一处理
UsernamePasswordAuthenticationFilter:默认的认证过滤器,从请求中读取表单用户名密码数据进行校验,如果是JSON提交需要对其进行重写
FilterSecurityInterceptor:是一个方法级的权限过滤器, 基本位于过滤链的最底部
 
自定义添加过滤器
除了SpringSecurity默认的过滤器,我们还可以添加自己的过滤器来进行自定义认证或授权。在SpringBoot开发中,SpringSecurity自动配置会向容器中自动注入相关过滤器,因此如果自己也有过滤器的情况下回导致过滤器顺序混乱,建议通过SpringSecurity统一管理过滤器。
 
如下,我们在自己的配置类中重写configure(HttpSecurity http)配置方法,自定义添加自己的过滤器
  1. 1 @Configuration //告诉SpringBoot该类是一个配置类,自动装配到IOC容器
  2. 2 @EnableWebSecurity //全局开启SpringSecurity
  3. 3 @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) //开启权限注解,之后会介绍
  4. 4 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  5. 5 @Override
  6. 6 protected void configure(HttpSecurity http) throws Exception {
  7. 7 //添加自定义过滤器在某过滤器前执行
  8. 8 http.addFilterBefore(wrapperFilter, UsernamePasswordAuthenticationFilter.class);
  9. 9 //添加自定义过滤器在某过滤器之后
  10. 10 http.addFilterAfter(filter,UsernamePasswordAuthenticationFilter.class);
  11. 11 //添加过滤器在最后
  12. 12 http.addFilter(filter);
  13. 13 }
  14. 14 }
 
配置常用组件:
WebSecurityConfigurerAdapter(Security配置适配器)
UsernamePasswordAuthentcationFilter(用户名密码认证过滤器)
UserDetailService(用户权限数据查询服务)
TokenRepository(记住我Token Dao)
PasswordEncoder(NoOpPasswordEncoder、BCryptPasswordEncoder加密方式)
 
 
HttpSecutity常用配置:
 
Remember(记住我):
  1. 1 .rememberMe()
  2. 2 .tokenRepository(tokenRepository) //记住我的token管理Dao,操作数据库的记住我缓存
  3. 3 .tokenValiditySeconds(60) //token的有效时长
 
formLogin(表单登录):
  1. 1 .formLogin()
  2. 2 .loginPage("/login_page") //登陆页面
  3. 3 .loginProcessingUrl("/login")          //登陆请求处理接口,Spring security默认的处理登录接口是/login这个自带的接口
  4. 4 .usernameParameter("name")           //指定用户名参数名称
  5. 5 .passwordParameter("passwd") //指定密码参数名称
  6. 6 .permitAll() //将登录操作url放行
 
authorizeRequests(url请求权限):
  1. .authorzeRequests()
  2. .antMatchers("/admin/**")
  3. .hasRole("ADMIN") //具备特定角色可访问
  4.  
  5. .antMatchers("/user/**")
  6. .access("hasAnyRole('ADMIN','USER')") //参数以表达式方式书写,多个以 and 连接
  7.  
  8. //除了.permitAll()的url,其余所有URL需要认证后访问
  9. .anyRequest()
  10. .authenticated()

logout(登出):

  1. 1 .logout()    //开启注销登陆
  2. 2 .logoutUrl("/logout")    //注销登陆请求url
  3. 3 .clearAuthentication(true)    //清除身份信息
  4. 4 .invalidateHttpSession(true)   //session失效
  5. 5 .addLogoutHandler(new LogoutHandler() {  //注销处理
  6. 6 @Override
  7. 7 public void logout(HttpServletRequest req,
  8. 8 HttpServletResponse resp,
  9. 9 Authentication auth) {
  10. 10
  11. 11 }
  12. 12 })
  13. 13 .logoutSuccessHandler(new LogoutSuccessHandler() { //注销成功处理
  14. 14 @Override
  15. 15 public void onLogoutSuccess(HttpServletRequest req,
  16. 16 HttpServletResponse resp,
  17. 17 Authentication auth)
  18. 18 throws IOException {
  19. 19 resp.sendRedirect("/login_page"); //跳转到自定义登陆页面
  20. 20 }
  21. 21 })
csrf(跨站脚本伪造):

1 .csrf().disabl(); //前后端分离时一般关闭

RemenberMe记住我(自动登录)原理:
 
总结配置流程
  • 认证用户实现UserDetails接口
  • 用户来源的Service实现UserDetailsService接口,实现loadUserByUsername()方法,从数据库中获取数据
  • 实现自己的过滤器继承UsernamePasswordAuthenticationFilter,重写attemptAuthentication()和successfulAuthentication()方法实现自己的逻辑
  • Spring Security的配置类继承自WebSecurityConfigurerAdapter,重写里面的两个config()方法
  • 如果使用RSA非对称加密,就准备好RSA的配置类,然后在启动类中加入注解将其加入IOC容器
 
CSRF跨站请求伪造
攻击者利用已经登录(认证)某网站的浏览器,向网站发起恶意请求
原理:攻击者利用某种方式让受害者浏览器发起请求访问正常登录过的网站地址,此时由于浏览器保存着网站Cookie,网站接收请求并处理操作。攻击者可以利用这种方式发起任何正常网站用户可以进行的操作。
 
要完成一次CSRF攻击,受害者必须依次完成两个步骤:
  1.登录受信任网站A,并在本地生成Cookie。
  2.在不登出A的情况下,访问危险网站B。
从Spring Security 4.0开始,默认情况下会启用CSRF保护,以防止CSRF 攻击应用程序,Spring Security CSRF会针对PATCH,POST,PUT和DELETE方法进行防护。
 
 
注解说明
权限校验
@EnableGlobalMethodSecurity:开启方法注解权限校验
参数:
  • securedEnable=true 开启@Securd注解
  • prePostEnable=true 开启@Preauthorize@PostAuthorize注解
 
@Securd("ROLE_xxx"):用户具有某个权限(角色)才能访问
@Preauthorize("hashAnyRole('ROLE_ADMIN')"):进入方法之前进行权限严重
 
  1. 1 @Service
  2. 2 public class MethodService {
  3. 3 @Secured("ROLE_ADMIN")     //访问此方法需要ADMIN角色
  4. 4 public String admin() {
  5. 5 return "hello admin";
  6. 6 }
  7. 7 @PreAuthorize("hasRole('ADMIN') and hasRole('DBA')") //访问此方法需要ADMIN且DBA
  8. 8 public String dba() {
  9. 9 return "hello dba";
  10. 10 }
  11. 11 @PreAuthorize("hasAnyRole('ADMIN','DBA','USER')") //三个都行
  12. 12 public String user() {
  13. 13 return "user";
  14. 14 }
  15. 15 }
参数过滤
@PostFilter:对返回值进行过滤
@PreFilter:对方法参数进行过滤
  用法:
  @PostFilter("filterObject.属性==xx"):过滤对象属性,当表达式为true时允许数据通过,为false的数据会被过滤掉
 
开起security
注解 @EnableWebSecurity在 Spring boot 应用中使用 Spring Security,用到了 @EnableWebSecurity注解,官方说明为,该注解和 @Configuration 注解一起使用, 注解 WebSecurityConfigurer 类型的类,或者利用@EnableWebSecurity 注解继承 WebSecurityConfigurerAdapter的类,这样就构成了 Spring Security 的配置。
 
 
 
单点登录相关

 
 
SpringSecurity总结理解:
 
SpringSecurity的配置非常灵活可拓展性很强,因此使用该安全组件可以完成很多自定义配置。首先分析项目中的几个要素:认证路径(登录处理)、需要放行的路径,需要授权的路径、是否使用session、是否禁用csrf、配置跨域过滤器、是否自定义认证成功后失败的逻辑处理、用户认证失败或权限不足的响应逻辑。
 
就以我现在的项目分析:
对于前后端分离的项目首先要考虑到禁用session和csrf因为我们用jwt token来解决http的无状态性,需要注意的是禁用session后SecurityContextHolder会失效,因为它默认依赖session来进行上下文处理。
然后对于静态资源的url放行处理,和对公开访问接口的放行处理,例如登录处理接口、注册接口、验证码获取接口等。做完这些放行处理之后,再对剩下所有的url进行认证拦截处理。
再然后就需要做对于token认证授权的一些适配配置问题进行自定义处理,比如登录成功后我们需要将用户的token存入redis,那么这个逻辑可以通过实现UsernamePasswordAuthenticationFilter然后重写successfulAuthentication和unsuccessfulAuthentication方法,在successfulAuthentication方法中我们可以自定义登录成功后的处理逻辑,如token处理和security上下文处理等。unsuccessfulAuthentication一般就返回失败就行了。注意我们自己实现的UsernamePasswordAuthenticationFilter想让他生效需要在配置中让他替换原来的通过http.addFilterAt(myUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
还有一种方法通过http.formLogin().successHandler().failureHandler();来设置认证成功和失败的处理器;
 
注意,如果我们使用token来维护状态,那么每个请求都是需要通过token来鉴权的,所以我们还需要写一个过滤器来维护token校验逻辑,写一个过滤器获取请求中的token做校验逻辑,校验处理成功后我们还可以将用户数据添加到SecurityContextHolder中,以便在后续处理中获取当前请求用户数据信息。
 
还有一个需要注意的地方,关于用户的认证校验逻辑,一般我们通过实现UsernamePasswordAuthenticationFilter并重写attemptAuthentication方法进行认证校验。还有一种方法是不实现UsernamePasswordAuthenticationFilter,而是提供一个我们的身份提供者,一个实现了AuthenticationProvider接口的类,然后将认证校验逻辑卸载authenticate()方法中,并且通过authenticationProvider()方式进行配置。
 
由过滤器链组成,通过配置可以开启或关闭特定过滤器,其中认证过滤器最终都会创建一个对应的XXXToken,例如UsernamePasswordAuthentication会创建一个UsernamePasswordAuthenticationToken。创建好了之后通过实现了authenticationManager接口的ProviderManager遍历所有实现了AuthenticationProvider身份提供者进行身份校验逻辑。注意每个ProviderManager都只处理自己关联的Token,如RememberMeAuthenticationProvider只处理RememberMeAuthenticationToken。当遍历到其中一个ProviderManager能够成功验证时用户就认证成功了。
 

你还不了解SpringSecurity吗?快来看看SpringSecurity实战总结~的更多相关文章

  1. 【SpringSecurity系列2】基于SpringSecurity实现前后端分离无状态Rest API的权限控制原理分析

    源码传送门: https://github.com/ningzuoxin/zxning-springsecurity-demos/tree/master/01-springsecurity-state ...

  2. 面试还搞不懂redis,快看看这40道面试题(含答案和思维导图)

    Redis 面试题 1.什么是 Redis?. 2.Redis 的数据类型? 3.使用 Redis 有哪些好处? 4.Redis 相比 Memcached 有哪些优势? 5.Memcache 与 Re ...

  3. 【转】面试还搞不懂redis,快看看这40道Redis面试题(含答案和思维导图)

    ———————————————— 版权声明:本文为CSDN博主「程序员追风」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明. 原文链接:https://blog. ...

  4. 金融数据分析还能这样做?快试试这个BI工具小白也能学会!

    说起银行.保险.股票投资等这些金融行业,大多数人都认为它们都是依靠数据驱动的企业,毕竟大数据的诞生本来就是为了金融信息流通而服务的,但是事实真的是这样吗? 事实并非如此,真正在金融行业做数据分析的人, ...

  5. 2020面试还搞不懂MyBatis?快看看这27道面试题!(含答案和思维导图)

    前言 MyBatis是一个优秀的持久层ORM框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注SQL 本身,而不需要花费精力去处理例如注册驱动.创建connection.创建statem ...

  6. Docker竟然还能这么玩?商业级4G代理搭建实战!

    时间过得真快,距离这个系列的上一篇文章<商业级4G代理搭建指南[准备篇]>发布的时间已经过了两个星期了,上个星期由于各种琐事缠身,周二开始就没空写文章了,所以就咕咕咕了. 那么在准备篇中, ...

  7. 轻松上手SpringBoot+SpringSecurity+JWT实RESTfulAPI权限控制实战

    前言 我们知道在项目开发中,后台开发权限认证是非常重要的,springboot 中常用熟悉的权限认证框架有,shiro,还有就是springboot 全家桶的 security当然他们各有各的好处,但 ...

  8. 【SpringSecurity系列1】基于SpringSecurity实现前后端分离无状态Rest API的权限控制

    源码传送门: https://github.com/ningzuoxin/zxning-springsecurity-demos/tree/master/01-springsecurity-state ...

  9. CyberArticle(eLib电子图书馆)网文快捕

    CyberArticle (网文快捕)是一款知识管理软件,主要致力于网页的保存和后期管理.CyberArticle (网文快捕)主要功能,就是收集和整理网页.利用CyberArticle (网文快捕) ...

随机推荐

  1. HDFS初探之旅(一)

    1.HDFS简介                                                                                            ...

  2. GO并发相关

    锁的使用 注意要成对,重点是代码中有分支或者异常返回的情况,这种情况要在异常返回前先释放锁 mysqlInstanceLock.Lock() slaveHostSql := "show sl ...

  3. vue2 中的 export import

    vue中组件的引用嵌套通过export import语法链接 Nodejs中的 export import P1.js export default { name: 'P1' } index.js i ...

  4. maven常用Java配置

    maven国内镜像 ------------------------------------------------------------------------------------------ ...

  5. 【Linux】【Shell】【text】Vim

    文本编辑器: 文本:纯文本,ASCII text:Unicode: 文本编辑种类: 行编辑器:sed 全屏编辑器:nano, vi vi: Visual Interface vim: Vi IMpro ...

  6. SQL注入 (1) SQL注入类型介绍

    SQL注入 SQL注入介绍与分类 1. 什么是sql注入 通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令. 2. sql注入类型 按照注入 ...

  7. IT服务生命周期

    一.概述 IT服务生命周期由规划设计(Pianning&Design).部署实施(Implementing).服务运营(Opera,tion).持续改进(Improvemenit)和监督管理( ...

  8. Linux服务器被黑 排查思路

    目录 一.为何会被入侵? 二.排查 入侵排查 检查是否还存在被登陆可能 计划任务 被修改的文件 筛选日志 日志恢复 找到异常进程-1 找到异常进程-2 找到异常进程-3 找到异常进程-4 三.总结 一 ...

  9. centos源码安装ruby

    目录 一.简介 二.程序部署 一.简介 Ruby,一种简单快捷的面向对象(面向对象程序设计)脚本语言.rvm是ruby的管理器,可以切换ruby版本,下载ruby. 二.程序部署 1.下载ruby w ...

  10. 服务器安装Centos7

    目录 一.安装 一.安装 1.开启虚拟机后会出现以下界面 Install CentOS 7 安装CentOS 7 Test this media & install CentOS 7 测试安装 ...