当前位置: 首页 > 面试题库 >

Spring Security OAuth2-@ EnableOauth2Sso,但也接受令牌作为身份验证

宿景曜
2023-03-14
问题内容

我有有一个应用程序@EnableOAuth2Sso上的WebSecurityConfigurerAdapter

添加@EnableOAuth2Sso应用程序后,会将我重定向到授权服务器,并在登录到该授权服务器后允许访问。我也想提供API访问权限,所以我希望应用程序能够通过Authorization-
Header传递一个访问令牌来访问我的资源。

Authorization: bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...

我通过与@EnableOAuth2Sso注意一起使用的身份验证筛选器进行了调试,未选中Authorization-Header值。

之后,我尝试创建自定义过滤器并将此过滤器添加到安全配置中

@Override
public void configure(HttpSecurity http) throws Exception {
  http.addFilter(myCustomFilter)
    ...;
}

但是现在我得到以下异常:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
    ... 26 more
Caused by: org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built
    at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:44)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain(WebSecurityConfiguration.java:105)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$f0788cea.CGLIB$springSecurityFilterChain$5(<generated>)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$f0788cea$$FastClassBySpringCGLIB$$7e95689d.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:318)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$f0788cea.springSecurityFilterChain(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)

起初,我以为自己在过滤器内做错了什么,但最终我得到了一个普通的过滤器类,除了继续执行过滤器链之外,什么也没做,仍然有相同的错误。

所以我有两个问题:

  1. 为什么会出现此异常?
  2. 在使用的应用程序中,是否可以对端点进行令牌身份验证@EnableOAuth2Sso

问题答案:

出现异常的原因是@jah所说的过滤器的顺序。

我做了什么,以达到所要求的认证,包含在授权标头的访问令牌,是创建一个类ApiTokenAccessFilter延伸OAuth2AuthenticationProcessingFilter。该过滤器采用ResourceServerTokenServices构造函数参数,并将无状态标志设置为false。

public class ApiTokenAccessFilter extends OAuth2AuthenticationProcessingFilter {

  public ApiTokenAccessFilter(ResourceServerTokenServices resourceServerTokenServices) {

    super();
    setStateless(false);
    setAuthenticationManager(oauthAuthenticationManager(resourceServerTokenServices));
  }

  private AuthenticationManager oauthAuthenticationManager(ResourceServerTokenServices tokenServices) {

    OAuth2AuthenticationManager oauthAuthenticationManager = new OAuth2AuthenticationManager();

    oauthAuthenticationManager.setResourceId("oauth2-resource");
    oauthAuthenticationManager.setTokenServices(tokenServices);
    oauthAuthenticationManager.setClientDetailsService(null);

    return oauthAuthenticationManager;
  }
}

在我的安全配置中,我使用了此过滤器,如下所示:

@Configuration
@EnableOAuth2Sso
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

  @Autowired
  private ResourceServerTokenServices tokenServices;

  @Override
  public void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests()
        .anyRequest()
        .authenticated()
        .and()
        .addFilterBefore(new ApiTokenAccessFilter(tokenServices), AbstractPreAuthenticatedProcessingFilter.class);
  }
}

我认为这可能会更容易,所以我在spring-security-oauth Github存储库上打开了一个问题。我不确定该解决方案是否可行,但是我没有找到其他选择。



 类似资料:
  • 我想扩展现有的迁移工具,以便在将文件导入到 SharePoint Online 之前对文件设置敏感度标签。我找到了微软信息保护SDK,它似乎提供了必要的API。 为了熟悉API,我下载并运行了ServicePrincipalAuth示例应用程序(请参见https://learn.microsoft.com/en-us/samples/azure-samples/mipsdk-dotnet-file

  • 我有一个LaravelAPI(实际上是LumenAPI)服务于VueJS前端。Vue应用程序允许用户登录到谷歌。然后将Google令牌发送回Lumen API,后者使用Google验证令牌,然后验证电子邮件地址是否为有效用户。然后它生成一个令牌,与用户一起存储在数据库中,并返回用户对象。 我没有使用Passport或jwt auth之类的东西。那么现在,我如何使用默认的Auth中间件来验证(现在已

  • 我按照教程,但它似乎不能正常工作与JWT,但它是确定的基本身份验证。 我下载并安装了JwtAuthForWebAPI。我还生成了JWT令牌并尝试执行API调用,但错误是。 我必须实现/修改任何东西来将索赔从JWT转移到线程。当前原则 我的代码非常简单:global.asax.cs: Web.config: 调用示例

  • 我刚刚开始在.NET中开发我的第一个REST API。由于它将是无状态的,我将使用令牌进行身份验证: 基本思想(System.Security.Cryptography): null 检查凭据是否有效(用户名,将哈希密码与db值进行比较) 如果为真,则加密数据对象 对生成的令牌使用HMAC,并将其存储到数据库 将令牌(不带HMAC)返回给用户(cookie/字符串) 对需要身份验证的方法的请求:

  • 我正在尝试在Dropwizard web应用程序中实现OAuth2身份验证。我已经创建了所需的<code>验证器 我所需的行为是,在我的客户端通过在我的登录页面上提供他/她的凭据登录后,我想将客户端重定向到我使用Dropwizard Views创建的问候语页面,并且路径为“/me”,如下所示: 我的问候资源如下所示: 目前,我得到一个“访问此资源需要凭据。”登录后的响应。在阅读了一些关于令牌认证的