spring-attic / spring-security-oauth-javaconfig

28 stars 35 forks source link

OAuth2ServerConfigurer should check to see if authorizedRequests has been applied #1

Open rwinch opened 10 years ago

rwinch commented 10 years ago

Error is something like:

java.lang.IllegalStateException: Cannot apply org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer@40e2580e to already built object
    at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.add(AbstractConfiguredSecurityBuilder.java:194)
    at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.apply(AbstractConfiguredSecurityBuilder.java:127)
    at org.springframework.security.config.annotation.web.builders.HttpSecurity.getOrApply(HttpSecurity.java:1348)
    at org.springframework.security.config.annotation.web.builders.HttpSecurity.authorizeRequests(HttpSecurity.java:684)
    at org.springframework.security.oauth2.config.annotation.web.configurers.OAuth2ServerConfigurer.configure(OAuth2ServerConfigurer.java:142)
    at org.springframework.security.oauth2.config.annotation.web.configurers.OAuth2ServerConfigurer.configure(OAuth2ServerConfigurer.java:66)
    at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.configure(AbstractConfiguredSecurityBuilder.java:378)
    at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.java:327)
    at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:39)
    at org.springframework.security.config.annotation.web.builders.WebSecurity.performBuild(WebSecurity.java:293)
    at org.springframework.security.config.annotation.web.builders.WebSecurity.performBuild(WebSecurity.java:74)
    at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.java:331)
    at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:39)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain(WebSecurityConfiguration.java:92)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerByCGLIB$$8e275241.CGLIB$springSecurityFilterChain$3(<generated>)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerByCGLIB$$8e275241$$FastClassByCGLIB$$83435244.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:326)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerByCGLIB$$8e275241.springSecurityFilterChain(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)
    ... 24 common frames omitted

Workaround is

http
    .authorizeRequests()
         .anyRequest().permitAll()
sirianni commented 8 years ago

The suggested workaround has the side effect of overriding any HttpSecurity configuration done in other WebSecurityConfigurerAdapters in the application. For example, when I apply the workaround it allows unprotected access to all resources in my app.

rwinch commented 8 years ago

@sirianni Sorry I wasn't clear. You can configure the authorization however you want. The key is to ensure that authorization is configured.

sirianni commented 8 years ago

Thanks @rwinch - yes, I think I understood that part. The problem is that I have an HttpSecurity configured already in a different WebSecurityConfigurerAdapter @Configuration in my app.

Given that, I expected that I would not need the workaround. However, without that workaround in my ResourceServerConfigurerAdapter class, I hit the above IllegalStateException.

My application has several WebSecurityConfigurerAdapter instances which (up until now) have worked cooperatively just fine. I guess I could try to merge all those into a single ResourceServerConfigurerAdapter config, but I'd rather not take that approach.

Any ideas?

sirianni commented 8 years ago

I've also tried adjusting the @Order of the ResourceServerConfigurer relative to the others WebSecurityConfigurers. No matter what I do:

  1. I need to include the http.authorizeRequests() as a workaround
  2. The http configuration specified in ResourceServerConfigurer overwrite anything configured in my other WebSecurityConfigurers.
sirianni commented 8 years ago

It looks like the ResourceServerConfiguration is building an entirely separate springSecurityFilterChain, overwriting the one I already have configured for my app.

Here is my normal chain:

Security filter chain: [
  WebAsyncManagerIntegrationFilter
  SecurityContextPersistenceFilter
  HeaderWriterFilter
  LogoutFilter
  TokenAuthenticationProcessingFilter
  UsernamePasswordAuthenticationFilter
  RequestCacheAwareFilter
  SecurityContextHolderAwareRequestFilter
  AnonymousAuthenticationFilter
  MdcFilter
  SessionManagementFilter
  ExceptionTranslationFilter
  FilterSecurityInterceptor
  SwitchUserFilter
]

By simply adding @EnableResourceServer my other filters (e.g. UsernamePasswordAuthenticationFilter, etc.) are removed, yielding:

Security filter chain: [
  WebAsyncManagerIntegrationFilter
  SecurityContextPersistenceFilter
  HeaderWriterFilter
  LogoutFilter
  OAuth2AuthenticationProcessingFilter
  RequestCacheAwareFilter
  SecurityContextHolderAwareRequestFilter
  AnonymousAuthenticationFilter
  SessionManagementFilter
  ExceptionTranslationFilter
  FilterSecurityInterceptor
]
sirianni commented 8 years ago

Is this related to spring-projects/spring-boot#4332 ?

sirianni commented 8 years ago

My intention is to have the same REST API endpoints (/api/**) guarded by:

  1. Traditional username/password/session-based authentication and authorization (via UserDetails with GrantedAuthorities, etc.)
  2. OAuth-based authorization (with bearer token).

The traditional authorization has been working well. I am now trying to layer in the OAuth piece. Is there a recommended configuration for such a scenario?

sirianni commented 8 years ago

Perhaps for such a setup I should forgo the ResourceServerConfiguration class and manually insert the OAuth2AuthenticationFilter into the Security Filter chain.

trygvis commented 7 years ago

@sirianni Can you show how you configured your app without using ResourceServerConfiguration?

sirianni commented 7 years ago

@trygvis - I ended up implementing my own filter to extract and validate the bearer token instead of using the Spring Security OAuth library.

pnukeid commented 7 years ago

@sirianni can you explain how you filter and extract and validate the bearer token... Some code maybe...

btw this issues still exist today...

Thx..

astropcrb commented 7 years ago

Any update on this issue? I am still experiencing it so it appears to not have been resolved.

Similar story to above. My http-configuration is overridden by @EnableResourceServer annotation. I have tried with @Order as well.

bitsofinfo commented 7 years ago

Still exists

eajitesh commented 6 years ago

I solved it in the following manner:

Got the inspiration for creating a custom implementation of SecurityMetadataSource from SpringSecurity book by Mick Knutson