15

I have a separate ResourceServer built using Spring-Security-oauth2. Here is the code RemoteTokenService.

@Bean
public ResourceServerTokenServices tokenService() {
   RemoteTokenServices tokenServices = new RemoteTokenServices();
   tokenServices.setClientId("sample_test_client_app");
   tokenServices.setClientSecret("secret");
   tokenServices.setCheckTokenEndpointUrl("http://localhost:8080/oauth/check_token");
   return tokenServices;
}

When I'm accessing the resource server with AccessToken I get the following:

FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /oauth/check_token; Attributes: [denyAll()]
FilterSecurityInterceptor - Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@c3f3b25: Principal: org.springframework.security.core.userdetails.User@3c0cd8e: Username: sample_test_client_app; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Not granted any authorities; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null; Not granted any authorities
AffirmativeBased - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@6172e10, returned: -1
ExceptionTranslationFilter - Access is denied (user is not anonymous); delegating to AccessDeniedHandler

Can any one tell me what is wrong with my configuration ?

Update : My Spring security configuration.

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.inMemoryAuthentication().withUser("developer").password("developer").roles("USER");

    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/webjars/**", "/images/**", "/oauth/uncache_approvals", "/oauth/cache_approvals");
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
                 http
            .authorizeRequests().antMatchers("/login.jsp").permitAll().and()
            .authorizeRequests().antMatchers("/oauth/check_token").permitAll().and()
            .authorizeRequests()
                .anyRequest().hasRole("USER")
                .and()
            .exceptionHandling()
                .accessDeniedPage("/login.jsp?authorization_error=true")
                .and()
            .logout()
                .logoutSuccessUrl("/index.jsp")
                .logoutUrl("/logout.do")
                .and()
            .formLogin();
        // @formatter:on
    }
}

My Auth server configuration.

@Configuration
    @EnableAuthorizationServer
    protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

        @Autowired
        private TokenStore tokenStore;

        @Autowired
        private UserApprovalHandler userApprovalHandler;

        @Autowired
        @Qualifier("authenticationManagerBean")
        private AuthenticationManager authenticationManager;

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            // @formatter:off
            clients
                .inMemory()
                .withClient("sample_test_client_app")
                .secret("secret")
                .authorizedGrantTypes("client_credentials","authorization_code")
                .authorities("ROLE_CLIENT")
                .resourceIds(CHANAKYA_RESOURCE_ID)
                .scopes("read","write");

            // @formatter:on
        }

        @Bean
        public TokenStore tokenStore() {
            return new InMemoryTokenStore();
        }

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler)
                    .authenticationManager(authenticationManager);
        }

        @Override
        public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
            oauthServer.realm("resource_server/client");
        }

    }
Pratik Shah
  • 1,782
  • 1
  • 15
  • 33
  • It looks like you have /check_token secured with `denyAll()`. That's probably a mistake, but to be able to correct it you'd have to show the code that broke it. – Dave Syer Oct 08 '14 at 12:32
  • Thanks a lot for this question, took me hours to find a proper solution :) – Yanire Romero Dec 09 '15 at 00:28

2 Answers2

14

I have the following configuration:

@Configuration
@EnableWebSecurity
@EnableAuthorizationServer
public class OAuthSecurityConfig extends AuthorizationServerConfigurerAdapter {
// ...
    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        // (!)
        oauthServer.allowFormAuthenticationForClients();
    }
// ...

I added the following line:

    oauthServer.checkTokenAccess("permitAll()");

into the line with "(!)" to fix the same problem.

Alex
  • 967
  • 4
  • 15
  • 38
  • That would be the key (it's off by default I guess). I would like the suggest that "permitAll()" might be a little too permissive. But it's your choice really. – Dave Syer Oct 08 '14 at 17:53
  • @DaveSyer agree. But this is for example only ;) – Alex Oct 08 '14 at 19:14
  • @DaveSyer yeah its off by default. – Pratik Shah Oct 09 '14 at 03:06
  • @Alex this works for me. but can you tell me how can I get ClientDetails at resource server so that I can check Client's Role for security. – Pratik Shah Oct 09 '14 at 03:36
  • I'm still waiting for your answer @DaveSyer. – Pratik Shah Oct 09 '14 at 03:41
  • @prtk_shah Could you add more details to your question about ClientDetails? As I understand your question Spring Security should verify client roles. – Alex Oct 09 '14 at 10:14
  • @Alex At Resource server I have a secured url e.g. "data/users" which is accessed only if "client" applicaiton has role "ROLE_CLIENT". Here I am using RemoteTokenService and I have a client configured at oauth server with role "ROLE_CLIENT" with client_credential grant.How can my client access this url ??? as I am using RemoteTokenService my token will be verified via "/oauth/check_token" (CheckTokenEndpoint). which dont give any information about client Role. So how can I compare Role of clients. – Pratik Shah Oct 09 '14 at 11:30
  • @prtk_shah see my answer below – Alex Oct 09 '14 at 12:12
1

At Resource server I have a secured url e.g. "data/users" which is accessed only if "client" applicaiton has role "ROLE_CLIENT". Here I am using RemoteTokenService and I have a client configured at oauth server with role "ROLE_CLIENT" with client_credential grant.How can my client access this url ???

All requests should include authorisation with type 'Bearer' and token:

> curl "https://localhost:8080/users/me" -H "Pragma: no-cache" -H "Origin:
> http://localhost:8080" -H "Accept-Encoding: gzip,deflate" -H
> "Accept-Language: en-US,en;q=0.8,es;q=0.6" -H "Authorization: Bearer
> f07abd25-af1f-44e2-XXXX-ba5071168XXX" -H "Accept: */*" -H
> "Cache-Control: no-cache" -H "User-Agent: Mozilla/5.0 (Windows NT 6.1;
> WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124
> Safari/537.36" -H "Connection: keep-alive" -H "Referer:
> http://localhost:8080/test.html" --compressed

as I am using RemoteTokenService my token will be verified via "/oauth/check_token" (CheckTokenEndpoint). which dont give any information about client Role. So how can I compare Role of clients.

Spring security has all required information. All you need to do is secure your endpoint. In my case:

@PreAuthorize("hasAnyAuthority('USER_READ')")

In this case only user with role 'USER_READ' can get access to my endpoint.


Feel free to ask any additional questions.

Alex
  • 967
  • 4
  • 15
  • 38
  • thanks for your answer. As you say "In this cas only user with role 'USER_ROLE' can get access to my endpoint". in Client_credential grant user is not there. it is related to only client. In that case when Resource server requestes to authorization server for token authentication outh server returns only client_id , token expire time and scopes of that client. so in that case how can I check hasAuthority ??? – Pratik Shah Oct 09 '14 at 12:19
  • @prtk_shah Correct, client info contains only such info http://pastie.org/9634116 but token info contains more information http://pastie.org/9634123. – Alex Oct 09 '14 at 12:55
  • thanks for this. but I am little bit confuse with your answer. can you explain me this in more detail that how can i get ClientAuthority while using RemoteTokenService and ClientCredential grant. and where do you get the above JSON? – Pratik Shah Oct 09 '14 at 16:43
  • @prtk_shah sorry, but I don't know it for this moment. May be I'm wrong in some points... I will check it today and let you know. About your second question: I made my implementation of TokenStore for storing tokens in MongoDB. – Alex Oct 10 '14 at 08:33
  • @prtk_shah I found the following line in the logs, it may be an answer on your question: '27789 [http-bio-8081-exec-1] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository - SecurityContext stored to HttpSession: 'org.springframework.security.core.context.SecurityContextImpl@cba196e7: Authentication: org.springframework.security.oauth2.provider.OAuth2Authentication@cba196e7: Principal: ; Credentials: [PROTECTED]; Authenticated: true; Details: remoteAddress=127.0.0.1, tokenValue=; Granted Authorities: USER_READ' – Alex Oct 10 '14 at 20:01
  • Thanks but I found what I'm looking for and I will post the correct answer asap and one more time thanks for you great help and effort. – Pratik Shah Oct 11 '14 at 03:21