相信有不少同学再刚接触 SpringSeccurity ,进行自定义登录页面时,当输入正确的用户名密码后但是提交一直提交不到登录逻辑的现象,那么有可能就是你的前台登录表单中设置的参数值名不对。
下面是一个非常简单的登录表单。我已经将两个参数值的 name 设置为 username
和 password
。
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>登录</title></head><body><!--登录表单--><formaction="/login"method="post"><label>用户名:<inputname="username"type="text"></label><br/><label>密码:<inputname="password"type="text"></label><br/><inputtype="submit"value="登录"></form></body></html>
登录表单中的 name 值必须为:username
和 password
,这两个参数名要跟UsernamePasswordAuthenticationFilter
中的设置要一样,否则接收不到。
那么为什么要这么设置呢?上源码。
我们主要查看 SpringSeccurity 下的 UsernamePasswordAuthenticationFilter
类的 attemptAuthentication()
方法。
publicAuthenticationattemptAuthentication(HttpServletRequestrequest, HttpServletResponseresponse) throwsAuthenticationException { //如果只允许 POST 请求或者请求方式不是 POST 方式时,抛异常if (this.postOnly&&!request.getMethod().equals("POST")) { thrownewAuthenticationServiceException("Authentication method not supported: "+request.getMethod()); } //通过 obtainUsername() 方法获取 request 域中的 username 值Stringusername=obtainUsername(request); username= (username!=null) ?username : ""; username=username.trim(); //通过 obtainPassword() 方法获取 request 域中的 password 值Stringpassword=obtainPassword(request); password= (password!=null) ?password : ""; UsernamePasswordAuthenticationTokenauthRequest=newUsernamePasswordAuthenticationToken(username, password); // Allow subclasses to set the "details" propertysetDetails(request, authRequest); returnthis.getAuthenticationManager().authenticate(authRequest); }
我们查看 obtainUsername()
方法可以看出来就是一个非常简单的 request.getParameter()
方法。
protectedStringobtainUsername(HttpServletRequestrequest) { returnrequest.getParameter(this.usernameParameter); }
同理,obtainPassword()
也是一个非常简单的 request.getParameter()
方法。
protectedStringobtainPassword(HttpServletRequestrequest) { returnrequest.getParameter(this.usernameParameter); }
那么 request.getParameter()
需要的参数 usernameParameter
和 usernameParameter
在 UsernamePasswordAuthenticationFilter
类的刚开始时已经赋值为 username
,password
。
看到这里已经不难明白,其实 Spring 就是通过 request 域中 username和 password的值来获取我们输入的用户名密码。如果前台登录表单参数名不是 username和 password,那自然获取不到,就会一直登录不了。
录表单参数名不是 username和 password,那自然获取不到,就会一直登录不了。
那么如何改成我们自己设置的参数名呢?
很简单,我们只需要在 SpringSecurityConfig
配置类中设置usernameParameter
和 passwordParameter
即可。
protectedvoidconfigure(HttpSecurityhttp) throwsException { //表单登录http.formLogin() //自定义登录页面 .loginPage("/login.html") //自定义登录逻辑 .loginProcessingUrl("/login") //登陆成功后跳转页面,必须是 POST 方式 .successForwardUrl("/toMain") //登录失败后跳转到错误页面,必须是 POST 方式 .failureForwardUrl("/toError") //设置参数名 .usernameParameter("username123") .passwordParameter("password123"); }