簡體   English   中英

Spring Security OAuth2 - @ EnableOauth2Sso,但也接受令牌作為身份驗證

[英]Spring Security OAuth2 - @EnableOauth2Sso but accept tokens as authentication, too

我有有一個應用程序@EnableOAuth2SsoWebSecurityConfigurerAdapter

添加@EnableOAuth2Sso ,應用程序會將我重定向到授權服務器,並允許在此授權服務器登錄后進行訪問。 我也想提供API訪問,所以我希望應用程序能夠通過Authorization-Header傳遞一個accessstoken來訪問我的資源

Authorization: bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9... 

我通過與@EnableOAuth2Sso注意到的身份驗證過濾器進行了@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 repo上打開了一個問題。 我不確定這種解決方案是否可行,但我沒有找到另一種選擇。

這是第一個問題的答案。 您收到此異常是因為您嘗試在不指定順序的情況下將過濾器添加到文件管理鏈。 過濾器鏈由固定順序的多個過濾器組成。 檢查是否存在要添加的過濾器時會拋出異常。 當其中發生異常時, AbstractSecurityBuilderorg.springframework.security.config.annotation.AlreadyBuiltException 因此, AbstractSecurityBuilder中發生的各種異常導致了這種無關的異常。

一種可能的方式來增加您的過濾器是使用該addFilterBefore(Filter filter, Class<? extends Filter> beforeFilter)addFilterAfter(Filter filter, Class<? extends Filter> afterFilter)的方法HttpSecurity

關於第二個問題,您應該提供更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM