SpringSecurity自定义UsernamePasswordAuthenticationFilter
UsernamePasswordAuthenticationFilter介绍
UsernamePasswordAuthenticationFilter是AbstractAuthenticationProcessingFilter针对使用用户名和密码进行身份验证而定制化的一个过滤器。其添加是在调用http.formLogin()时作用,默认的登录请求pattern为"/login",并且为POST请求。当我们登录的时候,也就是匹配到loginProcessingUrl,这个过滤器就会委托认证管理器authenticationManager来验证登录。
自定义UsernamePasswordAuthenticationFilter
这里我的需求是通过自定义UsernamePasswordAuthenticationFilter实现对前端传过来的密码进行RSA私钥解密,并且因为登录地址不是"/login",所以继承的是AbstractAuthenticationProcessingFilter,如果登录地址为默认,那么可直接继承UsernamePasswordAuthenticationFilter重写attemptAuthentication方法即可。
- public class MyUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
- public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
- public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";
- private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
- private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
- private boolean postOnly = true;
- private String privateKey = "xxxxxxxxxxxxxxxxxxx";
- public MyUsernamePasswordAuthenticationFilter() {
- super(new AntPathRequestMatcher("/oauth/token", "POST"));
- }
- public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
- throws AuthenticationException {
- if (postOnly && !request.getMethod().equals("POST")) {
- throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
- }
- String username = obtainUsername(request);
- String password = obtainPassword(request);
- try {
- password = RSAUtil.decrypt(password, privateKey);
- } catch (Exception e) {
- e.printStackTrace();
- }
- if (username == null) {
- username = "";
- }
- if (password == null) {
- password = "";
- }
- username = username.trim();
- UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
- // Allow subclasses to set the "details" property
- setDetails(request, authRequest);
- return super.getAuthenticationManager().authenticate(authRequest);
- }
- public void setAuthenticationManager(AuthenticationManager authenticationManager) {
- super.setAuthenticationManager(authenticationManager);
- }
- protected String obtainPassword(HttpServletRequest request) {
- return request.getParameter(passwordParameter).replaceAll(" ", "+");
- }
- protected String obtainUsername(HttpServletRequest request) {
- return request.getParameter(usernameParameter);
- }
- protected void setDetails(HttpServletRequest request,
- UsernamePasswordAuthenticationToken authRequest) {
- authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
- }
- public void setUsernameParameter(String usernameParameter) {
- Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
- this.usernameParameter = usernameParameter;
- }
- public void setPasswordParameter(String passwordParameter) {
- Assert.hasText(passwordParameter, "Password parameter must not be empty or null");
- this.passwordParameter = passwordParameter;
- }
- public void setPostOnly(boolean postOnly) {
- this.postOnly = postOnly;
- }
- public final String getUsernameParameter() {
- return usernameParameter;
- }
- public final String getPasswordParameter() {
- return passwordParameter;
- }
- }
把自定义 MyUsernamePasswordAuthenticationFilter 添加到 Filter Chain 过滤器链中
在 SpringSecurity 的配置类中使用 http.addFilterAt(myAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) 把自定义的过滤器放在UsernamePasswordAuthenticationFilter 的位置,并为其设置认证成功和失败的处理方法以及认证管理器AuthenticationManager
- @Configuration
- @EnableWebSecurity
- @EnableGlobalMethodSecurity(prePostEnabled = true)
- public class SecurityConfig extends WebSecurityConfigurerAdapter {
- @Autowired
- private AuthenticationSuccessHandler appLoginInSuccessHandler;
- @Bean
- @Override
- public AuthenticationManager authenticationManagerBean() throws Exception {
- AuthenticationManager manager = super.authenticationManagerBean();
- return manager;
- }
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- http.authorizeRequests().anyRequest().authenticated()
- .and().httpBasic().and()
- .cors().disable().headers().frameOptions().sameOrigin();// 解决iframe无法访问
- http.addFilterAt(myAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
- }
- @Bean
- MyUsernamePasswordAuthenticationFilter myAuthenticationFilter() throws Exception {
- MyUsernamePasswordAuthenticationFilter filter = new MyUsernamePasswordAuthenticationFilter();
- filter.setAuthenticationManager(authenticationManagerBean());
- filter.setAuthenticationSuccessHandler(appLoginInSuccessHandler);
- filter.setAuthenticationFailureHandler(new AuthenticationFailureHandler() {
- @Override
- public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
- response.setContentType("application/json;charset=utf-8");
- response.getWriter().write(JSON.toJSONString(Respon.failed("登录失败!")));
- }
- });
- return filter;
- }
- }
自定义UsernamePasswordAuthenticationFilter的运用
除了上面的例子,还常用于修改表单登录变为使用Json格式登录,登录验证码等等,需要注意的地方是UsernamePasswordAuthenticationFilter的默认登录地址为
SpringSecurity自定义UsernamePasswordAuthenticationFilter的更多相关文章
- SpringSecurity 自定义用户 角色 资源权限控制
SpringSecurity 自定义用户 角色 资源权限控制 package com.joyen.learning.security; import java.sql.ResultSet; impor ...
- SpringSecurity 自定义表单登录
SpringSecurity 自定义表单登录 本篇主要讲解 在SpringSecurity中 如何 自定义表单登录 , SpringSecurity默认提供了一个表单登录,但是实际项目里肯定无法使用的 ...
- Spring-Security 自定义Filter完成验证码校验
Spring-Security的功能主要是由一堆Filter构成过滤器链来实现,每个Filter都会完成自己的一部分工作.我今天要做的是对UsernamePasswordAuthenticationF ...
- SpringSecurity自定义AuthenticationProvider和AuthenticationFilter
AuthenticationProvider 默认实现:DaoAuthenticationProvider 授权方式提供者,判断授权有效性,用户有效性,在判断用户是否有效性,它依赖于UserDetai ...
- SpringSecurity自定义过滤器
applicationContext-security.xml: <beans:beans xmlns="http://www.springframework.org/schema/s ...
- SpringSecurity自定义登陆页面和跳转页面
如果我们不用form-login说明登陆界面,springsecurity框架将自动为我们生成登陆界面 现在我们不想用自动生成的登陆界面了,而想使用自定义的漂亮的登陆界面 则需要使用<secur ...
- springSecurity自定义认证配置
上一篇讲了springSecurity的简单入门的小demo,认证用户是在xml中写死的.今天来说一下自定义认证,读取数据库来实现认证.当然,也是非常简单的,因为仅仅是读取数据库,权限是写死的,因为相 ...
- SpringSecurity自定义注解和处理器
登录功能 添加一个配置类 @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Reso ...
- Spring-Security自定义登录页&inMemoryAuthentication验证
Spring Security是为基于Spring的应用程序提供声明式安全保护的安全性框架.框架下内容比较多,可以做到按照角色权限对请求路径进行限制.今天主要验证自定义登录页,在内存用户存储中进行请求 ...
随机推荐
- 关于int的范围以及溢出问题
最近在练一些算法题目的时候恰巧碰到了几道关于int范围与溢出相关的问题,于是就整理一下. 1.原码.补码 在计算机中数值都是用补码表示和存储的(正数补码与原码一致,负数补码是原码符号位不变,其余位取反 ...
- Appium+python自动化(三十二)- 代码写死一时爽,框架重构火葬场 - PageObject+unittest(超详解)
简介 江湖有言:”代码写死一时爽,框架重构火葬场“,更有人戏言:”代码动态一时爽,一直动态一直爽
- (二十)c#Winform自定义控件-有后退的窗体
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- 上传文件时 重新载入页面以获取源代码 http://*/upload.php
今天做一个处理上传文件的接口时碰到这样一个问题, 用的是element-ui的上传组件,但是上传失败, 抓包一看返回的是 重新载入页面以获取源代码 http://*/upload.php 网上搜了一下 ...
- 从零开始一起学习SLAM | 用四元数插值来对齐IMU和图像帧
视觉 Vs. IMU 小白:师兄,好久没见到你了啊,我最近在看IMU(Inertial Measurement Unit,惯性导航单元)相关的东西,正好有问题求助啊 师兄:又遇到啥问题啦? 小白:是这 ...
- 如何使用python records 库优雅的操作数据库
今天要介绍的这个python第三方库非常厉害,完美操作各种数据库.名字叫 records, 在网上很少有这个库的相关资料,但是在开源社区可是很火热的哦.如果这还不能打消你的顾虑,再告诉你一件事:如果你 ...
- 使用base64编码把背景添加到CSS文件中
最近博客背景图片的外链挂了,没办法,只好另找办法. 在博客园后台,有一个“文件”菜单,可以上传自己的文件,我就打算把图片传到里面.但却发现了一个很反人性的设置:不允许上传jpg,png文件,允许上传的 ...
- Okhttp3源码解析(4)-拦截器与设计模式
### 前言 回顾: [Okhttp的基本用法](https://www.jianshu.com/p/8e404d9c160f) [Okhttp3源码解析(1)-OkHttpClient分析](htt ...
- 完结撒花!129 集 21 个小时,松哥自制的 Spring Boot2 系列视频教程杀青啦!
松哥的 Spring Boot 教程分为几个阶段. 2016 松哥最早在 2016 年底的时候开始写 Spring Boot 系列的教程,记得当时在广州上班,年底那段时间在深圳出差,在深圳人生地不熟, ...
- Leetcode之回溯法专题-46. 全排列(Permutations)
Leetcode之回溯法专题-46. 全排列(Permutations) 给定一个没有重复数字的序列,返回其所有可能的全排列. 示例: 输入: [1,2,3] 输出: [ [1,2,3], [1,3, ...