基于Spring Security令牌的身份验证

我有一个REST API,我正在使用Spring

Security基本授权进行身份验证,客户端会为每个请求发送用户名和密码。现在,我想实现基于令牌的身份验证,当用户最初通过身份验证时,我将在响应标头中发送令牌。对于进一步的请求,客户端可以在令牌中包含该令牌,该令牌将用于对资源进行用户身份验证。我有两个身份验证提供程序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中,我设置自定义userDetailsS​​ervice并通过从数据库中获取用户登录详细信息进行身份验证(只要使用Authorization:Basic

bGllQXBpVXNlcjogN21wXidMQjRdTURtR04pag ==作为标题来传递用户名和密码,就可以正常工作)

但是,当我使用X-AUTH-

TOKEN(为Constants.AUTH_HEADER_NAME)在标头中包含令牌时,没有调用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安全性的当前行为。

回答:

这是我能够实现基于令牌的身份验证和基本身份验证的方式

SpringSecurityConfig.java

@Configuration

@EnableWebSecurity

public class SecurityConfig extends WebSecurityConfigurerAdapter

{

@Override

public void configure(final AuthenticationManagerBuilder auth) throws Exception

{

auth.userDetailsService(this.participantService).passwordEncoder(this.passwordEncoder());

}

@Override

protected void configure(final HttpSecurity http) throws Exception

{

//Implementing Token based authentication in this filter

final TokenAuthenticationFilter tokenFilter = new TokenAuthenticationFilter();

http.addFilterBefore(tokenFilter, BasicAuthenticationFilter.class);

//Creating token when basic authentication is successful and the same token can be used to authenticate for further requests

final CustomBasicAuthenticationFilter customBasicAuthFilter = new CustomBasicAuthenticationFilter(this.authenticationManager() );

http.addFilter(customBasicAuthFilter);

}

}

TokenAuthenticationFilter.java

    public class TokenAuthenticationFilter extends GenericFilterBean

{

@Override

public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)

throws IOException, ServletException

{

final HttpServletRequest httpRequest = (HttpServletRequest)request;

//extract token from header

final String accessToken = httpRequest.getHeader("header-name");

if (null != accessToken) {

//get and check whether token is valid ( from DB or file wherever you are storing the token)

//Populate SecurityContextHolder by fetching relevant information using token

final User user = new User(

"username",

"password",

true,

true,

true,

true,

authorities);

final UsernamePasswordAuthenticationToken authentication =

new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());

SecurityContextHolder.getContext().setAuthentication(authentication);

}

chain.doFilter(request, response);

}

}

CustomBasicAuthenticationFilter.java

@Component

public class CustomBasicAuthenticationFilter extends BasicAuthenticationFilter {

@Autowired

public CustomBasicAuthenticationFilter(final AuthenticationManager authenticationManager) {

super(authenticationManager);

}

@Override

protected void onSuccessfulAuthentication(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response, final Authentication authResult) {

//Generate Token

//Save the token for the logged in user

//send token in the response

response.setHeader("header-name" , "token");

}

}

由于我们的CustomBasicAuthenticationFilter已配置并添加为Spring安全性的过滤器,

只要基本身份验证成功,请求就会重定向到onSuccessfulAuthentication,在此我们设置令牌,并在响应中使用一些标头“ header-

name”发送它。

如果发送“ header-name”以请求进一步的请求,则该请求将在尝试尝试基本身份验证之前先通过TokenAuthenticationFilter。

以上是 基于Spring Security令牌的身份验证 的全部内容, 来源链接: utcz.com/qa/420860.html

回到顶部