春季启动。 HMAC认证。 如何添加自定义AuthenticationProvider和身份validationfilter?

为了实现HMAC身份validation,我创建了自己的filter,提供者和令牌。 RestSecurityFilter:

public class RestSecurityFilter extends AbstractAuthenticationProcessingFilter { private final Logger LOG = LoggerFactory.getLogger(RestSecurityFilter.class); private AuthenticationManager authenticationManager; public RestSecurityFilter(String defaultFilterProcessesUrl) { super(defaultFilterProcessesUrl); } public RestSecurityFilter(RequestMatcher requiresAuthenticationRequestMatcher) { super(requiresAuthenticationRequestMatcher); } @Override public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { AuthenticationRequestWrapper request = new AuthenticationRequestWrapper(req); // Get authorization headers String signature = request.getHeader("Signature"); String principal = request.getHeader("API-Key"); String timestamp = request.getHeader("timestamp"); if ((signature == null) || (principal == null) || (timestamp == null)) unsuccessfulAuthentication(request, response, new BadHMACAuthRequestException("Authentication attempt failed! Request missing mandatory headers.")); // a rest credential is composed by request data to sign and the signature RestCredentials credentials = new RestCredentials(HMACUtils.calculateContentToSign(request), signature); // Create an authentication token return new RestToken(principal, credentials, Long.parseLong(timestamp)); } @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { LOG.debug("Filter request: " + req.toString()); HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; chain.doFilter(request, response); Authentication authResult; try { authResult = attemptAuthentication(request, response); if (authResult == null) unsuccessfulAuthentication(request, response, new BadHMACAuthRequestException("Authentication attempt failed !")); } catch (InternalAuthenticationServiceException failed) { LOG.error("An internal error occurred while trying to authenticate the user.", failed); unsuccessfulAuthentication(request, response, failed); } catch (AuthenticationException failed) { // Authentication failed unsuccessfulAuthentication(request, response, failed); } } } 

认证提供者:

 @Component public class RestAuthenticationProvider implements AuthenticationProvider { private final Logger LOG = LoggerFactory.getLogger(RestAuthenticationProvider.class); private ApiKeysService apiKeysService; @Autowired public void setApiKeysService(ApiKeysService apiKeysService) { this.apiKeysService = apiKeysService; } @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { RestToken restToken = (RestToken) authentication; // api key (aka username) String principal = restToken.getPrincipal(); LOG.info("Authenticating api key: '" + principal + "'"); // check request time, 60000 is one minute long interval = Clock.systemUTC().millis() - restToken.getTimestamp(); if ((interval  60000)) throw new BadHMACAuthRequestException("Auth Failed: old request."); // hashed blob RestCredentials credentials = restToken.getCredentials(); // get secret access key from api key ApiKey apiKey = apiKeysService.getKeyByName(principal).orElseThrow(() -> new NotFoundException("Key not found for: '" + principal + "'")); String secret = apiKey.getApiKey(); // calculate the hmac of content with secret key String hmac = HMACUtils.calculateHMAC(secret, credentials.getRequestData()); LOG.debug("Api Key '{}', calculated hmac '{}'"); // check if signatures match if (!credentials.getSignature().equals(hmac)) { throw new BadHMACAuthRequestException("Auth Failed: invalid HMAC signature."); } return new RestToken(principal, credentials, restToken.getTimestamp(), apiKeysService.getPermissions(apiKey)); } @Override public boolean supports(Class authentication) { return RestToken.class.equals(authentication); } } 

我不知道如何配置WebSecurityConfig来使用我的filter和身份validation提供程序对每个请求进行身份validation。 我假设我需要创建@Bean来初始化RestSecurityFilter 。 另外, AbstractAuthenticationProcessingFilter JavaDoc说我需要authenticationManager属性。 我很感激使用自定义filter,提供者和令牌的工作解决方案

我不熟悉Spring Boot,但是我看到你对我的问题的评论如何在自定义filter中使用Java配置注入AuthenticationManager

在传统的Spring Security XML配置中,您可以像这样指定自定义RestSecurityFilter

    

更多信息http://docs.spring.io/spring-security/site/docs/4.0.1.RELEASE/reference/htmlsingle/#ns-custom-filters