我有一个休息api,我在使用spring security Basic Authorization进行身份验证,其中客户端为每个请求发送用户名和密码 . 现在,我想实现基于令牌的身份验证,我将在用户首先进行身份验证时在响应头中发送令牌 . 对于进一步的请求,客户端可以在标头中包含该标记,该标记将用于向用户验证资源 . 我有两个身份验证提供程序tokenAuthenticationProvider和daoAuthenticationProvider
@Component
public class TokenAuthenticationProvider implements AuthenticationProvider {
@Autowired
private TokenAuthentcationService service;
@Override
public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
final RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
final HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
final String token = request.getHeader(Constants.AUTH_HEADER_NAME);
final Token tokenObj = this.service.getToken(token);
final AuthenticationToken authToken = new AuthenticationToken(tokenObj);
return authToken;
}
@Override
public boolean supports(final Class<?> authentication) {
return AuthenticationToken.class.isAssignableFrom(authentication);
}
}
在daoAuthenticationProvider中,我设置自定义userDetailsService并通过从数据库中获取用户登录详细信息进行身份验证(只要使用授权传递用户名和密码,该工作正常:基本bGllQXBpVXNlcjogN21wXidMQjRdTURtR04pag ==作为标头)
但是当我使用X-AUTH-TOKEN(即Constants.AUTH_HEADER_NAME)在标头中包含token时,不会调用tokenAuthenticationProvider . 我收到错误了
{"timestamp":1487626368308,"status":401,"error":"Unauthorized","message":"Full authentication is required to access this resource","path":"/find"}
以下是我添加身份验证提供程序的方法 .
@Override
public void configure(final AuthenticationManagerBuilder auth) throws Exception {
final UsernamePasswordAuthenticationProvider daoProvider = new
UsernamePasswordAuthenticationProvider(this.service, this.passwordEncoder());
auth.authenticationProvider(this.tokenAuthenticationProvider);
auth.authenticationProvider(daoProvider);
}
请建议如何在不损害spring安全性的当前行为的情况下实现基于令牌的身份验证 .
2 回答
以下是我能够实现基于令牌的身份验证和基本身份验证的方法
SpringSecurityConfig.java
TokenAuthenticationFilter.java
CustomBasicAuthenticationFilter.java
由于我们的CustomBasicAuthenticationFilter已经配置并添加为 spring 安全性的过滤器,
每当基本身份验证成功时,请求将被重定向到onSuccessfulAuthentication,我们在其中设置令牌并将其发送到响应中,并带有一些标头“header-name” .
如果发送“header-name”以进一步请求,则在尝试尝试基本身份验证之前,请求将首先通过TokenAuthenticationFilter .
您可以尝试在身份验证过滤器中设置自定义
AuthenticationToken
令牌,例如: