Spring Security OAuth2 – @ EnableOauth2Sso,但也接受令牌作为身份validation
我有一个在@EnableOAuth2Sso
上有@EnableOAuth2Sso
的应用程序
添加@EnableOAuth2Sso
,应用程序会将我重定向到授权服务器,并允许在此授权服务器登录后进行访问。 我也想提供API访问,所以我希望应用程序能够通过Authorization-Header传递一个accessstoken来访问我的资源
Authorization: bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
我通过与@EnableOAuth2Sso
注意到的身份validationfilter进行了@EnableOAuth2Sso
,未检查Authorization-Header值。
之后我尝试创建自定义filter并将此filter添加到安全配置中
@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() at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$f0788cea$$FastClassBySpringCGLIB$$7e95689d.invoke() 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() 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)
起初我以为我在我的filter中做了一些错误但我最终得到了一个简单的filter类除了继续过滤链并且仍然有相同的错误。
所以我有两个问题:
- 为什么我会得到这个例外?
- 有没有办法允许对使用
@EnableOAuth2Sso
的应用程序中的端点进行令牌认证?
exception的原因是像@jah这样的filter的排序。
我在Authorization-Header中实现包含访问令牌的请求身份validation所做的是创建一个扩展OAuth2AuthenticationProcessingFilter
的类OAuth2AuthenticationProcessingFilter
。 此filter采用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; } }
在我的安全配置中,我使用此filter如下:
@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上打开了一个问题。 我不确定这个解决方案是否可行,但我没有找到另一种选择。
这是您第一个问题的答案。 您收到此exception是因为您尝试在不指定订单的情况下将filter添加到文件管理链。 filter链由固定顺序的多个filter组成。 在检查是否存在要添加的filter时会抛出exception。 当其中发生exception时, AbstractSecurityBuilder
的org.springframework.security.config.annotation.AlreadyBuiltException
。 因此, AbstractSecurityBuilder
中发生的各种exception导致了这种无关的exception。
添加filter的一种可能方法是使用addFilterBefore(Filter filter, Class extends Filter> beforeFilter)
或者addFilterAfter(Filter filter, Class extends Filter> afterFilter)
的addFilterAfter(Filter filter, Class extends Filter> afterFilter)
方法。
关于第二个问题,您应该提供更多信息。