我有一个Spring Web应用程序,当前正在使用HTTP基本身份验证,使用用户名和密码,在标头中传递。我想添加要通过身份验证请求传入的其他字段,包括(可选)安全答案和设备ID。我想切换到在请求体内传递此信息,这样我就可以轻松扩展UsernamePasswordAuthenticationFilter。
我在WebSecurityConfig中有这个:
@Override
protected void configure(HttpSecurity http) throws Exception
{
http
.authorizeRequests()
.antMatchers(permitAllUrls)
.permitAll();
http
.addFilterAt(new MobileUserAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
http.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/");
http
.authorizeRequests()
.antMatchers("/**")
.hasRole("USER")
.and()
.csrf()
.requireCsrfProtectionMatcher(new NoAntPathRequestMatcher(nonCsrfUrls))
.and()
.addFilterAfter(new CsrfGrantingFilter(), SessionManagementFilter.class);
}
MobileUserAuthenticationFilter
(目前)是一个扩展UsernamePasswordAuthenticationFilter
的空类。向登录端点发送请求成功调用attemptAuthentication
UsernamePasswordAuthenticationFilter
方法。但是,收到的请求正文似乎是空的。
这是UsernamePasswordAuthenticationFilter
的内部(为清晰起见,省略了不必要的代码):
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;
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);
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 this.getAuthenticationManager().authenticate(authRequest);
}
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(usernameParameter);
}
protected void setDetails(HttpServletRequest request,
UsernamePasswordAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}
单步调查显示request
的{{1}}参数不包含任何参数(它正在调用attemptAuthentication
)。添加调试表达式request.getParameter("username")
将返回空枚举。
我的传出请求是:
request.getParameterNames()
但是到达过滤器时,用户名和密码都为空。我缺少什么,是否需要添加一些内容以允许过滤器接受请求主体?