问题描述
在我的用例中,我没有用于验证用户密码的User DB表。我正在使用客户端在API请求中发送的HMAC签名。在服务器端,我计算相同的HMAC签名,只需要匹配它们即可成功进行身份验证。
因此,我正在考虑使用Spring Security提供的DaoAuthenticationProvider
,而无需编写自己的自定义提供程序类。
以下是我所有的文件。当我@Autowired private UserDetailsService userDetailsService
时,我的Spring引导应用程序无法构建。我想念什么吗?
@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 (将#修改为@)