当前位置: 首页 > 知识库问答 >
问题:

身份验证Manager.authenticate方法没有被调用

欧阳狐若
2023-03-14

我试图按照API密钥身份验证代码从这个答案:https://stackoverflow.com/a/48448901

我创建了我的过滤器类:

package com.propfinancing.CADData.web;

import javax.servlet.http.HttpServletRequest;
import org.slf4j.LoggerFactory;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;

public class PullAPIKeyFromHeaderFilter extends AbstractPreAuthenticatedProcessingFilter {
  private String apiKeyHeaderName;
  
  public PullAPIKeyFromHeaderFilter(String apiKeyHeaderName) {
    this.apiKeyHeaderName = apiKeyHeaderName;
  }
  
  @Override
  protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
    String headerValue = request.getHeader(apiKeyHeaderName);
    return request.getHeader(headerValue);
  }

  @Override
  protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
    return apiKeyHeaderName;
  }
}

然后我实现了我的安全配置:

package com.propfinancing.CADData.web;

import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

@Configuration
@EnableWebSecurity
@Order(1)
public class APIKeySecurityConfig extends WebSecurityConfigurerAdapter {
  @Value("${caddata.apiKey.header.name}")
  private String apiKeyHeaderName;

  @Value("${caddata.apiKey}")
  private String apiKey;

  @Override
  protected void configure(HttpSecurity httpSecurity) throws Exception {
    PullAPIKeyFromHeaderFilter pullAPIKeyFromHeaderfilter = new PullAPIKeyFromHeaderFilter(apiKeyHeaderName);
    
    AuthenticationManager authManager = new AuthenticationManager() {
      @Override
      public Authentication authenticate(Authentication authentication) 
      throws AuthenticationException {
        String principal = (String) authentication.getPrincipal();
        if (!apiKey.equals(principal))
          throw new BadCredentialsException("Invalid API key");
        authentication.setAuthenticated(true);
        return authentication;
      }
    };
    pullAPIKeyFromHeaderfilter.setAuthenticationManager(authManager);
    
    httpSecurity.antMatcher("/**");
    httpSecurity.addFilter(pullAPIKeyFromHeaderfilter);
    httpSecurity.requiresChannel().anyRequest().requiresSecure();
    httpSecurity.csrf().disable();
    httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry urlAuthConfigurer = httpSecurity.authorizeRequests();
    ExpressionUrlAuthorizationConfigurer<HttpSecurity>.AuthorizedUrl authorizedUrl = urlAuthConfigurer.anyRequest();
    authorizedUrl.authenticated();
  }
}

当我用头作为请求的一部分对应用程序进行外部调用时,我得到一个403禁止响应。我可以看到过滤器从头中拉出键。这部分正在工作。

但是,不会调用authenticate()方法来检查头是否有效。我不确定我错过了什么,代码在我看来是一样的。

有什么想法吗?

共有2个答案

薛滨海
2023-03-14

我无法让上面的代码正常工作,但我改变了它,在该线程上使用了第二个答案https://stackoverflow.com/a/63852212正如预期的那样。

逄学潞
2023-03-14

看起来基类不对https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/web/authentication/preauth/AbstractPreAuthenticatedProcessingFilter.html :

这样做的目的只是从传入的请求中提取有关主体的必要信息,而不是对它们进行身份验证。

试着扩展https://docs.spring.io/spring-security/site/docs/4.0.x/apidocs/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.html。

 类似资料:
  • null 原因:javax.net.ssl.sslhandShakeException:在java.base/sun.security.ssl.alert.createsslException(Alert.java:128)在java.base/sun.security.ssl.alert.createsslException(Alert.java:117)在java.base/sun.secur

  • 是否可以使用Kerberos但不使用JAAS来验证用户/密码?

  • 我的问题类似于不调用Resteasy Bean验证。不过,那里的解决方案并不奏效。 我使用的是Restease3.0.9。最终与resteasy-validator提供者-11在我的pom。我正在使用一个定制的码头类启动整件事。 奇怪的是,验证在@PathParams上运行良好,但在bean上却不行。 在这种情况下,myParam上的@Size约束可以正常工作。但是MyBean中的@NotNull

  • 授权服务器可以支持任何与其安全要求匹配的合适的HTTP身份验证方案。当使用其他身份验证方法时,授权服务器必须定义客户端标识(注册记录)和认证方案之间的映射。

  • 我在REST api中使用JWT承载身份验证方案。为了在成功身份验证后将jwt令牌返回给客户端,目前我在正文中使用访问令牌响应,如中所述https://www.rfc-editor.org/rfc/rfc6750#page-10 但是也需要在其他HTTP请求中返回令牌,例如已经存在正文的注册。因此,正在考虑为其使用“身份验证信息”标头。但是承载方案没有在任何地方指定“身份验证信息”标头。我应该使用

  • 我正在尝试使用Facebook凭据实现网站登录。当我在Facebook小部件上按“取消”或“确定”时,我会看到不同的反应。当我按Cancel时,我看到以下内容 这是可预测的。但是当我按OK时,我看到另一个错误。 我在本地运行的网站Ubuntu 14.04 apache Web服务器与80端口。我怀疑错误的Facebook应用程序设置,但不知道调试什么。 此外,我可以提到推特登录也在相同的设置下工作