关于使SpringSecurity登录参数使用requestBody后引发的一系列问题及解决

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

之前写了一篇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)) 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值