聊聊SwitchUserFilter的使用
为什么80%的码农都做不了架构师?>>>
序
本文就来介绍一下如何使用SwitchUserFilter进行账户切换
filter顺序
spring security内置的各种filter:
Alias | Filter Class | Namespace Element or Attribute |
---|---|---|
CHANNEL_FILTER | ChannelProcessingFilter | http/intercept-url@requires-channel |
SECURITY_CONTEXT_FILTER | SecurityContextPersistenceFilter | http |
CONCURRENT_SESSION_FILTER | ConcurrentSessionFilter | session-management/concurrency-control |
HEADERS_FILTER | HeaderWriterFilter | http/headers |
CSRF_FILTER | CsrfFilter | http/csrf |
LOGOUT_FILTER | LogoutFilter | http/logout |
X509_FILTER | X509AuthenticationFilter | http/x509 |
PRE_AUTH_FILTER | AbstractPreAuthenticatedProcessingFilter Subclasses | N/A |
CAS_FILTER | CasAuthenticationFilter | N/A |
FORM_LOGIN_FILTER | UsernamePasswordAuthenticationFilter | http/form-login |
BASIC_AUTH_FILTER | BasicAuthenticationFilter | http/http-basic |
SERVLET_API_SUPPORT_FILTER | SecurityContextHolderAwareRequestFilter | http/@servlet-api-provision |
JAAS_API_SUPPORT_FILTER | JaasApiIntegrationFilter | http/@jaas-api-provision |
REMEMBER_ME_FILTER | RememberMeAuthenticationFilter | http/remember-me |
ANONYMOUS_FILTER | AnonymousAuthenticationFilter | http/anonymous |
SESSION_MANAGEMENT_FILTER | SessionManagementFilter | session-management |
EXCEPTION_TRANSLATION_FILTER | ExceptionTranslationFilter | http |
FILTER_SECURITY_INTERCEPTOR | FilterSecurityInterceptor | http |
SWITCH_USER_FILTER | SwitchUserFilter | N/A |
可以看到SwitchUserFilter是spring security提供的filter里头order顺序在最后的一个。
前面讲到了FilterSecurityInterceptor主要用来进行鉴权处理,而SwitchUserFilter是用来做账户切换的,把它放在FilterSecurityInterceptor之后,是要求对切换用户的功能进行鉴权,否则任何人都可以随意切换用户,那就安全故障了。
config
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true,jsr250Enabled = true,prePostEnabled = true
)
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Beanpublic SwitchUserFilter switchUserFilter(UserDetailsService userDetailsService) throws Exception {SwitchUserFilter switchUserFilter = new SwitchUserFilter();switchUserFilter.setUserDetailsService(userDetailsService);switchUserFilter.setTargetUrl("/session");return switchUserFilter;}@Overrideprotected void configure(HttpSecurity http) throws Exception {//Each <http> namespace block always creates an SecurityContextPersistenceFilter, an ExceptionTranslationFilter and a FilterSecurityInterceptor. These are fixed and cannot be replaced with alternatives.http.addFilterAfter(switchUserFilter(userDetailsService()),FilterSecurityInterceptor.class).exceptionHandling().authenticationEntryPoint(new UnauthorizedEntryPoint()).and().csrf().disable().authorizeRequests().antMatchers("/login","/css/**", "/js/**","/fonts/**").permitAll().antMatchers("/session").authenticated().antMatchers("/login/impersonate").hasAuthority("ROLE_ADMIN").antMatchers("/logout/impersonate").hasAuthority(SwitchUserFilter.ROLE_PREVIOUS_ADMINISTRATOR).and().formLogin().permitAll().and().logout().deleteCookies("JSESSIONID").permitAll();}@Bean@Overrideprotected UserDetailsService userDetailsService(){InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();manager.createUser(User.withUsername("demoUser1").password("123456").authorities("ROLE_USER","read_x").build());manager.createUser(User.withUsername("admin").password("123456").authorities("ROLE_ADMIN").build());return manager;}
}
SwitchUserFilter默认的切换账号的url为/login/impersonate,默认注销切换账号的url为/logout/impersonate,默认的账号参数为username
使用
上面的配置为了方便验证,把切换完用户的targetUrl设置为/session,其代码如下
@RestController
@RequestMapping("/session")
public class SessionController {@GetMapping("")public Object getCurrentUser(){return SecurityContextHolder.getContext().getAuthentication();}
}
首先用普通用户登录,访问http://localhost:8080/login/impersonate?username=admin,发现返回403
注销,使用管理员登录,访问http://localhost:8080/login/impersonate?username=demoUser1,发现成功并跳转到session
{"authorities": [{"authority": "ROLE_USER"},{"authority": "read_x"},{"source": {"authorities": [{"authority": "ROLE_ADMIN"}],"details": {"remoteAddress": "0:0:0:0:0:0:0:1","sessionId": null},"authenticated": true,"principal": {"password": null,"username": "admin","authorities": [{"authority": "ROLE_ADMIN"}],"accountNonExpired": true,"accountNonLocked": true,"credentialsNonExpired": true,"enabled": true},"credentials": null,"name": "admin"},"authority": "ROLE_PREVIOUS_ADMINISTRATOR"}],"details": {"remoteAddress": "0:0:0:0:0:0:0:1","sessionId": "1BF3D6F40A6F488EFD3ABE8F80E52872"},"authenticated": true,"principal": {"password": "123456","username": "demoUser1","authorities": [{"authority": "ROLE_USER"},{"authority": "read_x"}],"accountNonExpired": true,"accountNonLocked": true,"credentialsNonExpired": true,"enabled": true},"credentials": "123456","name": "demoUser1"
}
可以发现有成功切换
之后再切换回来 http://localhost:8080/logout/impersonate?username=demoUser1
{"authorities": [{"authority": "ROLE_ADMIN"}],"details": {"remoteAddress": "0:0:0:0:0:0:0:1","sessionId": null},"authenticated": true,"principal": {"password": null,"username": "admin","authorities": [{"authority": "ROLE_ADMIN"}],"accountNonExpired": true,"accountNonLocked": true,"credentialsNonExpired": true,"enabled": true},"credentials": null,"name": "admin"
}
可以发现切换回来了,是不是非常神奇,太强大了,以后线上排查问题之类的,非常方便,爽歪歪了简直
- 异常情况 如果你切换了不存在的用户,则报
This application has no explicit mapping for /error, so you are seeing this as a fallback.Sat Dec 16 14:36:28 CST 2017
There was an unexpected error (type=Unauthorized, status=401).
Authentication Failed: demoUser2
小结
SwitchUserFilter是个强大的filter,非常方便测试环境进行调试、测试,甚至可以用来进行上线问题排查。
转载于:https://my.oschina.net/go4it/blog/1591720
聊聊SwitchUserFilter的使用相关推荐
- 面向对象设计原则_聊聊面向对象的6大设计原则
程序员都知道编程有 3 大类:面向过程.面向对象.面向函数.面向对象是被讨论的最多的,个人认为,这是因为 Java 之类的编程语言有强大的用户基础,本质还是因为比较符合人的直觉. 说到面向对象,大家可 ...
- python邮件发送哪个好_最全总结!聊聊 Python 发送邮件的几种方式
1. 前言 邮件,作为最正式规范的沟通方式,在日常办公过程中经常被用到 我们都知道 Python内置了对 SMTP 的支持,可以发送纯文本.富文本.HTML 等格式的邮件 本文将聊聊利用 Python ...
- 今天聊聊分布式锁 No.86
好了切入正题,一直在工作中会聊到很多锁的问题,今天跟大家一起闲聊一下,究竟什么是锁,为什么需要锁,以及分布式的情况下,怎么设计和实现锁. 什么是锁? 明·魏禧<大铁椎传>上是这样解释的: ...
- 聊聊找工作中的项目经验问题(推荐系统和智能问答)
在求职过程中有这么一句话叫做"金九银十",也就是说,很多时候,求职的黄金时期就是在九月份和十月份,这两个月份中企业需求是最多的,求职的成功率也是最高的.但是随着AI方面的人才越来越 ...
- 聊聊Service Mesh:linkerd
[编者的话]随着企业逐渐将传统的单体应用向微服务或云原生应用的转变,虽然微服务或者云原生应用能给企业带来更多的好处,但也会带来一些具有挑战的问题,如怎么管理从单体应用转向微服务所带来的服务间通讯的复杂 ...
- 庖丁解牛迭代器,聊聊那些藏在幕后的秘密
0x00 前言 \\ 在我之前的一篇博客<细说C#:不是"栈类型"的值类型,从生命周期聊存储位置>的最后,我以总结和后记的方式涉及到一部分迭代器的知识.但是觉得还是不够 ...
- 聊聊Unsafe的一些使用技巧
记得初学 Java 那会,刚学完语法基础,就接触到了反射这个 Java 提供的特性,尽管在现在看来,这是非常基础的知识点,但那时候无疑是兴奋的,瞬间觉得自己脱离了"Java 初学者" ...
- 聊聊 TCP 长连接和心跳那些事
1 前言 可能很多 Java 程序员对 TCP 的理解只有一个三次握手,四次挥手的认识,我觉得这样的原因主要在于 TCP 协议本身稍微有点抽象(相比较于应用层的 HTTP 协议):其次,非框架开发者不 ...
- 聊聊算法在面试中的地位
前段时间,有一位好友找到我,向我打听阿里社招笔试是否看重算法题的考察,我给予了肯定的答复.他表现的有些沮丧,表示自己工程底子很扎实,框架源码也研究地很透彻,唯独算法能力不行,leetcode 上的简单 ...
最新文章
- [c#]解决方案:需要“jquery”ScriptResourceMapping。请添加一个名为 jquery (区分大小写)的 ScriptResourceMapping。
- 你连原理都还没弄明白?java文档注释快捷键idea
- 如何实施异构服务器的负载均衡及过载保护?
- gen already exists but is not a source folder
- 在 .NET 中加载椭圆曲线 (EC) 密钥
- C++王者之路 | C++的sizeof 与C语言的sizeof
- python联科_联科集团携手阿里云发布科研混合云平台 共建科研教育新生态
- 【正交幅度调制 QAM】
- vue-router 源码:实现一个简单的 vue-router
- Rider+EmmyLua lua代码高亮设置
- 使用css画出一条虚线
- xcode5 自定义模板
- 做事的常识 书籍梗概 小仓广
- 【前端】性能优化 - WebP
- c语言0和1二进制,二进制0和1代表什么
- css -- 为什么:last-child 无效?
- 华三服务器管理口地址_h3c 的交换机怎样设置管理地址?
- 2018年上海交通大学数学建模竞赛暑期夏令营讲课课件(完整版)
- Qt之实现3D纹理渲染自由旋转空间立方体
- Intellij IDEA如何在一个窗口同时打开多个Maven项目