之前写了一篇SpringSecurity整合Redis实现单点登录及认证返回json数据,这个本来只是作为先来学习的总结笔记,但最近终于有用武之地了。
公司新项目成立,我临危受命负责web端项目的搭建和开发,安全框架选型正是SpringSecurity。但SpringSecurity登录操作默认的参数形式是url参数(就是http://xx.xx.xx:xx/login?username=xx&password=xx这样),我们需要将参数放到requestBody中,于是
登录参数放到requestBody中
经过一通盲试,并没有找到通过配置实现这种需求的方法,于是我决定面向百度编程。网上的资料没有想象的多,但是还是找到了解决办法。
我发现负责登录认证的filter类名称为UsernamePasswordAuthenticationFilter,其关键代码如下:
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
if (this.postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
String username = obtainUsername(request);
username = (username != null) ? username : "";
username = username.trim();
String password = obtainPassword(request);
password = (password != null) ? password : "";
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
@Nullable
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(this.passwordParameter);
}
@Nullable
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(this.usernameParameter);
}
我们可以看到,这个类获取参数的方式,就是getParameter,所以基本上我们只要重写obtainPassword和obtainUsername方法就能满足我们的需求了,如果还想丰富一下,那直接重写attemptAuthentication就好了,我选择的是后者,代码如下:
@Slf4j
public class CustomAuthenticationProcessingFilter extends UsernamePasswordAuthenticationFilter {
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
try {
String bodyString = getBodyString(request);
if (!StringUtils.hasText(bodyString)) {
throw new IllegalArgumentException("用户名或密码不能为空");
}
Map<String, Object> map = new JacksonJsonParser().parseMap(bodyString);
if (!request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("不支持该方法: " + request.getMethod());
}
String username = obtainUsername(map);
username = username.trim();
if (!StringUtils.hasText(username))

本文详细讲述了如何在SpringSecurity中修改默认的url参数登录方式,实现从requestBody接收JSON数据进行认证,并修复单点登录失效的问题,最终通过创建自定义配置器来确保登录过滤器生效。
最低0.47元/天 解锁文章
1953

被折叠的 条评论
为什么被折叠?



