Spring Security-无法自动连接DaoAuthenticationProvider中的UserDetailsS​​ervice

问题描述

在我的用例中,我没有用于验证用户密码的User DB表。我正在使用客户端在API请求中发送的HMAC签名。在服务器端,我计算相同的HMAC签名,只需要匹配它们即可成功进行身份验证。

因此,我正在考虑使用Spring Security提供的DaoAuthenticationProvider,而无需编写自己的自定义提供程序类。

以下是我所有的文件。当我@Autowired private UserDetailsService userDetailsService时,我的Spring引导应用程序无法构建。我想念什么吗?

RESTSecurityConfig

@Configuration
@EnableWebSecurity
@Order(1)
public class RESTSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;      // <---- build fails when I try to autowire

    @Bean
    public RESTSecurityFilter authenticationFilter() throws Exception {
        RESTSecurityFilter authenticationFilter = new RESTSecurityFilter("/");
        authenticationFilter.setAuthenticationManager(authenticationManagerBean());
        return authenticationFilter;
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService);
        return provider;
    }

    
    @Autowired
    public void configAuthentication(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(authenticationProvider());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {          
        http.authorizeRequests().anyRequest().authenticated().and().addFilterBefore(authenticationFilter(),UsernamePasswordAuthenticationFilter.class);
    }
}

RESTSecurityFilter

public class RESTSecurityFilter extends AbstractAuthenticationProcessingFilter {

private static final Logger log = LoggerFactory.getLogger(RESTSecurityFilter.class);
private static final String ACCESS_KEY_ParaMETER_NAME = "x-access-key";
private static final String SIGNATURE_ParaMETER_NAME = "x-signature";
private static final String NONCE_ParaMETER_NAME = "x-nonce";
private static final String TIMESTAMP_ParaMETER_NAME = "x-timestamp";
private static final String SECRET_KEY = "xxxxxxxxxxxxxxxxx";

protected RESTSecurityFilter(String defaultFilterProcessesUrl) {
    super(defaultFilterProcessesUrl);
}

@Override
public Authentication attemptAuthentication(HttpServletRequest request,HttpServletResponse response)
        throws AuthenticationException,IOException,servletexception {
    String accessKey = getHeaderValue(request,ACCESS_KEY_ParaMETER_NAME);
    String signature = getHeaderValue(request,SIGNATURE_ParaMETER_NAME);
    String nonce = getHeaderValue(request,NONCE_ParaMETER_NAME);
    String timestamp = getHeaderValue(request,TIMESTAMP_ParaMETER_NAME);       
    String message = accessKey + ":" + nonce + ":" + timestamp;
    String hashSignature = null;
    try {
        hashSignature = HMacUtility.calculateHmac(message,SECRET_KEY);
        log.info("hashSignature : {}",hashSignature);
    }
    catch (InvalidKeyException | SignatureException | NoSuchAlgorithmException e) {
        e.printstacktrace();
    }

    AbstractAuthenticationToken authRequest = createAuthenticationToken(accessKey,new RESTCredentials(signature,hashSignature));

    // Allow subclasses to set the "details" property
    setDetails(request,authRequest);

    return this.getAuthenticationManager().authenticate(authRequest);
}

@Override
protected void successfulAuthentication(HttpServletRequest request,HttpServletResponse response,FilterChain chain,Authentication authResult) throws IOException,servletexception {
    super.successfulAuthentication(request,response,chain,authResult);
    chain.doFilter(request,response);
}

private String getHeaderValue(HttpServletRequest request,String headerParameterName) {
    return (request.getHeader(headerParameterName) != null) ? request.getHeader(headerParameterName) : "";
}

private AbstractAuthenticationToken createAuthenticationToken(String apikeyvalue,RESTCredentials restCredentials) {
    return new RESTAuthenticationToken(apikeyvalue,restCredentials);
}

protected void setDetails(HttpServletRequest request,AbstractAuthenticationToken authRequest) {
    authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}

@Override
protected boolean requiresAuthentication(HttpServletRequest request,HttpServletResponse response) {
    return true;
}
}

RESTCredentials

public final class RESTCredentials {
    private String requestSalt;
    private String secureHash;
    private RESTCredentials() {}

    public RESTCredentials(String requestSalt,String secureHash) {
        this.requestSalt = requestSalt;
        this.secureHash = secureHash;
    }

    public String getRequestSalt() {
        return requestSalt;
    }

    public String getSecureHash() {
        return secureHash;
    }
}

RESTAuthenticationToken

public class RESTAuthenticationToken extends UsernamePasswordAuthenticationToken {    
    private static final long serialVersionUID = 1L;

    public RESTAuthenticationToken(Object principal,Object credentials) {
        super(principal,credentials);
    }

    public RESTAuthenticationToken(Object principal,Object credentials,Collection<? extends GrantedAuthority> authorities) {
        super(principal,credentials,authorities);
    }    
}

有没有提供程序的简单有效的方法来在过滤器中对API进行身份验证吗?我在过滤器中都有“签名”和“ hashSignature”,所以只想比较它们,如果两个匹配就返回API json响应。

谢谢

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)