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的应用程序提供声明式安全保护的安全性框架.框架下内容比较多,可以做到按照角色权限对请求路径进行限制.今天主要验证自定义登录页,在内存用户存储中进行请求 ...
随机推荐
- node一键发布,并运行
作为一个前端开发人员如果你只会写一些业务代码,从程序员的角度来考虑已经可以了.但是从架构的角度来考虑那远远不够: 在此记录下成长中的经历: 想要达成的目的:运行一个脚本实现代码的打包,上传至服务器并部 ...
- 你真的了JMeter解聚合报告么?
1.背景 大家在使用JMeter进行性能测试时,聚合报告(Aggregate Report)可以说是必用的监听器,但是你真的了解聚合报告么? 2.目的 本次笔者跟大家聊聊聚合报告(Aggregate ...
- AutoResetEvent控制线程用法
本文主要来自一道面试题,由于之前对AutoResetEvent的用户很模糊(即使已经使用过了).面试题题目很简洁:两个线程交替打印0~100的奇偶数.你可以先动手试试,我主要是尝试在一个方法里面完成这 ...
- 【Spring Boot】利用 Spring Boot Admin 进行项目监控管理
利用 Spring Boot Admin 进行项目监控管理 一.Spring Boot Admin 是什么 Spring Boot Admin (SBA) 是一个社区开源项目,用于管理和监视 Spri ...
- Gradle 是什么
写在前面的话,最近在系统的学习Gradle,本来想写一篇关于 Gradle 的介绍. 但在官网发现了这篇关于 Gradle 的介绍,已经介绍的很好了,我就很直接翻译过来了. 原文地址 https:// ...
- Python学习 之 计算机基础
第一章 计算机基础 1.1 硬件 计算机基本的硬件由:CPU / 内存 / 主板 / 硬盘 / 网卡 / 显卡 等组成,只有硬件但硬件之间无法进行交流和通信 1.2 操作系统 操作系统用于协同或控制硬 ...
- Django之ORM-model模型关系
模型类关系 1)一对多关系例:图书类-英雄类 models.ForeignKey() 定义在多的类中. 2)多对多关系例:新闻类-新闻类型类 体育新闻 国际新闻models.ManyToManyFie ...
- Python面试总结篇
Python Coding Interview Questions and Answers 面试题一:逻辑运算赋值 v1 = 1 or 9 v2 = 0 or 9 # print(v1, v2)会输出 ...
- slice splice(数组) 和 slice substr substring split (字符串)的区别
array.slice(start,end)slice()如果不传入参数二,那么将从参数一的索引位置开始截取,一直到数组尾如果两个参数中的任何一个是负数,array.length会和它们相加 stri ...
- HBase的安装和使用
文章作者:foochane 原文链接:https://foochane.cn/article/2019062801.html 1 Hbase基本介绍 Hbase是一个分布式数据库,可以提供数据的实时 ...