1
votes

I've downloaded SpringSecurity OAuth2 test code from github and started the vanilla server by running the main Application class.

From Spring documentation:

The URL paths provided by the framework are /oauth/authorize (the authorization endpoint), /oauth/token (the token endpoint)

I want to test these 2 endpoints using postman, simulating a client credentials grant flow. But if I try to access those endpoints e.g https://localhost:8083/oauth/authorize with Basic Auth, giving the username 'user' and password 'password', I get "full authentication is required to access this resource".

What is missing in that project to be able to retrieve an authorization header code response from this request?

Code is below:

Application.java

package demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@EnableResourceServer
@RestController
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @RequestMapping("/")
    public String home() {
        return "Hello World";
    }

    @RequestMapping(value = "/", method = RequestMethod.POST)
    @ResponseStatus(HttpStatus.CREATED)
    public String create(@RequestBody MultiValueMap<String, String> map) {
        return "OK";
    }

    @Configuration
    @EnableAuthorizationServer
    protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {

        @Autowired
        private AuthenticationManager authenticationManager;

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

        @Override
        public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
            security.checkTokenAccess("isAuthenticated()");
        }

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            // @formatter:off
            clients.inMemory()
                    .withClient("myapp")
                    .secret("myappsecret")
                    .resourceIds("myresources")
                    .authorizedGrantTypes("client_credentials","refresh_token")
                    .authorities("USER")
                    .scopes("read", "write", "trust")
                    .accessTokenValiditySeconds(3000)
                    .refreshTokenValiditySeconds(3000)
            .and()
                .withClient("my-trusted-client")
                    .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
                    .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
                    .scopes("read", "write", "trust")
                    .resourceIds("oauth2-resource")
                    .accessTokenValiditySeconds(600)
                    .redirectUris("http://anywhere")
            .and()
                .withClient("my-client-with-registered-redirect")
                    .authorizedGrantTypes("authorization_code")
                    .authorities("ROLE_CLIENT")
                    .scopes("read", "trust")
                    .resourceIds("oauth2-resource")
                    .redirectUris("http://anywhere?key=value")
            .and()
                .withClient("my-client-with-secret")
                    .authorizedGrantTypes("client_credentials", "password")
                    .authorities("ROLE_CLIENT")
                    .scopes("read")
                    .resourceIds("oauth2-resource")
                    .secret("secret");
        // @formatter:on
        }

    }

}

Application.yml

spring:
  application:
    name: vanilla
management:
  context_path: /admin
security:
  user:
    password: password
  oauth2:
    resource:
      filter-order: 3
server:
  port: 8083      
logging:
  level:
    org.springframework.security: WARN

Postman request: enter image description here

Server Log:

2018-08-01 08:25:24.166  INFO 18524 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8083 (http)
    2018-08-01 08:25:24.172  INFO 18524 --- [           main] demo.Application                         : Started Application in 6.514 seconds (JVM running for 7.163)
    2018-08-01 08:25:41.709  INFO 18524 --- [nio-8083-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
    2018-08-01 08:25:41.709  INFO 18524 --- [nio-8083-exec-2] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
    2018-08-01 08:25:41.761  INFO 18524 --- [nio-8083-exec-2] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 52 ms
    2018-08-01 08:25:41.791 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/css/**']
    2018-08-01 08:25:41.791 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/oauth/authorize'; against '/css/**'
    2018-08-01 08:25:41.791 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/js/**']
    2018-08-01 08:25:41.791 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/oauth/authorize'; against '/js/**'
    2018-08-01 08:25:41.791 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/images/**']
    2018-08-01 08:25:41.791 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/oauth/authorize'; against '/images/**'
    2018-08-01 08:25:41.791 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/webjars/**']
    2018-08-01 08:25:41.791 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/oauth/authorize'; against '/webjars/**'
    2018-08-01 08:25:41.791 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/**/favicon.ico']
    2018-08-01 08:25:41.791 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/oauth/authorize'; against '/**/favicon.ico'
    2018-08-01 08:25:41.791 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/error']
    2018-08-01 08:25:41.791 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/oauth/authorize'; against '/error'
    2018-08-01 08:25:41.791 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : No matches found
    2018-08-01 08:25:41.791 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/oauth/token']
    2018-08-01 08:25:41.791 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/oauth/authorize'; against '/oauth/token'
    2018-08-01 08:25:41.792 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/oauth/token_key']
    2018-08-01 08:25:41.792 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/oauth/authorize'; against '/oauth/token_key'
    2018-08-01 08:25:41.792 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/oauth/check_token']
    2018-08-01 08:25:41.792 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/oauth/authorize'; against '/oauth/check_token'
    2018-08-01 08:25:41.792 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : No matches found
    2018-08-01 08:25:41.792 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/oauth/authorize'; against '/admin/**'
    2018-08-01 08:25:41.792 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/**']
    2018-08-01 08:25:41.792 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request '/oauth/authorize' matched by universal pattern '/**'
    2018-08-01 08:25:41.792 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : matched
    2018-08-01 08:25:41.793 DEBUG 18524 --- [nio-8083-exec-2] o.s.security.web.FilterChainProxy        : /oauth/authorize at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
    2018-08-01 08:25:41.794 DEBUG 18524 --- [nio-8083-exec-2] o.s.security.web.FilterChainProxy        : /oauth/authorize at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
    2018-08-01 08:25:41.797 DEBUG 18524 --- [nio-8083-exec-2] o.s.security.web.FilterChainProxy        : /oauth/authorize at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter'
    2018-08-01 08:25:41.798 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@c3dc28b
    2018-08-01 08:25:41.798 DEBUG 18524 --- [nio-8083-exec-2] o.s.security.web.FilterChainProxy        : /oauth/authorize at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
    2018-08-01 08:25:41.798 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', GET]
    2018-08-01 08:25:41.798 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/oauth/authorize'; against '/logout'
    2018-08-01 08:25:41.798 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', POST]
    2018-08-01 08:25:41.798 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /oauth/authorize' doesn't match 'POST /logout
    2018-08-01 08:25:41.798 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', PUT]
    2018-08-01 08:25:41.798 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /oauth/authorize' doesn't match 'PUT /logout
    2018-08-01 08:25:41.798 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', DELETE]
    2018-08-01 08:25:41.798 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /oauth/authorize' doesn't match 'DELETE /logout
    2018-08-01 08:25:41.798 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.web.util.matcher.OrRequestMatcher  : No matches found
    2018-08-01 08:25:41.798 DEBUG 18524 --- [nio-8083-exec-2] o.s.security.web.FilterChainProxy        : /oauth/authorize at position 5 of 11 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
    2018-08-01 08:25:41.800 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.w.a.www.BasicAuthenticationFilter  : Basic Authentication Authorization header found for user 'my-client-with-secret'
    2018-08-01 08:25:41.801 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
    2018-08-01 08:25:41.803 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.a.dao.DaoAuthenticationProvider    : User 'my-client-with-secret' not found
    2018-08-01 08:25:41.805 DEBUG 18524 --- [nio-8083-exec-2] o.s.s.w.a.www.BasicAuthenticationFilter  : Authentication request for failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
    2018-08-01 08:25:41.805 DEBUG 18524 --- [nio-8083-exec-2] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
1
You cannot call oauth/authorize endpoint with client credentials, you have to call oauth/token endpoint. - dur
That helped me, I thought that I could call the endpoints separately in postman, but if I select in the Type combobox the option OAuth2 instead of Basic Auth and fill the fields in the 'Get new access token' the server successfully gives me an access key. - Bruno Calça

1 Answers

2
votes

This could help someone.

To test API with Oauth 2.0 authorisation

  1. Open the authorization tab.

enter image description here

  1. Select Oauth 2.0 from the drop-down.
  2. Select Get New Access Token. enter image description here
  3. Fill up the details and click Request Token

enter image description here

Note : Based on the grand Type you choose, you will either get token or will prompt to authorize in Authorization server.