在springboot微服务中基于令牌的身份验证有哪些不同的方法?

时间:2017-10-19 14:18:48

标签: java spring authentication spring-boot spring-security

我有一个springboot微服务。这是由React客户端调用的。 react客户端通过登录表单对用户进行身份验证并将其登录。它使用我们的自定义身份验证服务。成功登录后,会发出JWT类型的令牌并保存在浏览器的本地存储中,然后客户端在调用微服务时通过HTTP Authorization标头提交。这是我实现的代码片段。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    // ...  
    @Override
    protected void configure(HttpSecurity http) throws Exception {
      super.configure(http);
      http.csrf().disable().headers().frameOptions().disable()
      .and().sessionManagement()
      .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
      .and().authorizeRequests().antMatchers("/api/**").authenticated()
      .antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
      .antMatchers("/swagger-resources/configuration/ui").permitAll()
      .antMatchers("/health/**").permitAll()
      .and()
      .addFilterBefore(new JWTAuthorizationFilter(new MyAuthenticationProvider()),
                        UsernamePasswordAuthenticationFilter.class);
    }
}

我有自己的AuthenticationProvider实现,用于对我们的内部auth服务进行实际身份验证。这是我的过滤器类。为简单起见,我删除了不必要的代码。

public class JWTAuthorizationFilter extends OncePerRequestFilter {
    private static final String UNAUTHORIZED_ERROR = "UNAUTHORIZED";
    public static final String X_AUTHORIZATION_HEADER = "X-Authorization";
    private static final String BEARER = "Bearer ";
    private final Logger log = LoggerFactory.getLogger(JWTAuthorizationFilter.class);
    private final AuthenticationProvider authenticationProvider;

    public JWTAuthorizationFilter(AuthenticationProvider authProvider) {
        super();
        this.authenticationProvider = authProvider;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        try {
            String token = resolveToken(request);
            Authentication authentication = this.authenticationProvider
                    .authenticate(new UsernamePasswordAuthenticationToken(null, token));
            SecurityContextHolder.getContext().setAuthentication(authentication);
            // invoking the next chain in the filter.
            filterChain.doFilter(request, response);
        } catch (AuthenticationException e) {
            log.error("Security exception for user {} - {}", e.getMessage());
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, UNAUTHORIZED_ERROR);
        }
    }

    private String resolveToken(HttpServletRequest request) {
        return request.getHeader(X_AUTHORIZATION_HEADER);
    }
}

一切正常。然后我进行了代码审查,当时coulegue要求我使用AbstractAuthenticationProcessingFilter代替OncePerRequestFilter / GenericFilterBean。我检查了文档[1],它说AbstractAuthenticationProcessingFilter主要用于基于浏览器的基于HTTP的身份验证请求。

顺便说一句,我尝试通过在那里移动我当前正在运行的逻辑来实现它,并将其与我的springboot微服务连接起来。但不幸的是,当我发送请求时,它给了我301永久HTTP状态代码和一些HTML用于登录表单。

这是我的问题。

  1. 我可以使用AbstractAuthenticationProcessingFilter作为此令牌吗? 认证。如果是这样的话怎么办?
  2. 为什么我在连接后将301永久移动ERROR 我的服务。
  3. 我当前的方法可能会出现任何可能出现的错误,漏洞或性能问题吗?
  4. 基于令牌的身份验证有哪些其他方式,它们的优缺点是什么?
  5. 我查看了春季安全参考指南,但找不到上述问题的具体答案。

    不幸的是,我无法共享我的代码,因为它使用了组织内部的一些专有库。我为此道歉。任何帮助表示赞赏。

    [1] https://docs.spring.io/autorepo/docs/spring-security/4.0.3.RELEASE/apidocs/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.html

0 个答案:

没有答案