Denis Steinman
Denis Steinman

Reputation: 7819

Can't use an access token in Spring OAuth2

I got access and refresh tokens from my Spring Boot app:

curl -X POST -d "client_id=clientIdPassword&grant_type=password&[email protected]&password=123@Qwerty" -H "Authorization: Basic Y2xpZW50SWRQYXNzd29yZDpzZWNyZXQ=" http://localhost:8082/oauth/token

Response:

{
    "access_token":"b57f72b5-43c2-49ac-88ce-43d50e9d39b4",
    "token_type":"bearer",
    "refresh_token":"7d58c9a1-e924-4a9f-8583-01770d1f667c",
    "expires_in":41727,
    "scope":""
}

But when I am trying to send request with this access token, my app redirects me to the login page.

curl -X POST -GET -H "Authorization: Bearer b57f72b5-43c2-49ac-88ce-43d50e9d39b4" -v http://localhost:8082/users
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8082 (#0)
> POST /users HTTP/1.1
> Host: localhost:8082
> User-Agent: curl/7.55.1
> Accept: */*
> Authorization: Bearer b57f72b5-43c2-49ac-88ce-43d50e9d39b4
> 
< HTTP/1.1 302 
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Set-Cookie: JSESSIONID=93B47C0FB5A11A651BC0A12AC8FBE021; Path=/; HttpOnly
< Location: http://localhost:8082/login
< Content-Length: 0
< Date: Sat, 17 Feb 2018 03:10:38 GMT
< 
* Connection #0 to host localhost left intact

What's wrong with my request? Below my controller:

@RequestMapping("users")
@RestController
@EnableWebMvc
@Validated
public class UserController {

    @Autowired
    protected UserManager mUserManager;

    @PreAuthorize("#oauth2.hasScope('read')")
    @PostMapping(value = "new")
    public ResponseEntity<UserModel> add(@RequestBody NewUserModel newUser) {
        User user = UserUtils.toUser(mUserManager, newUser);

        if (!mUserManager.add(user)) {
            throw new InternalServerException(ServerError.INTERNAL);
        }

        UserModel model = new UserModel(user);

        return new ResponseEntity<>(model, HttpStatus.CREATED);
    }

    @GetMapping
    public Page<UserModel> all(@RequestParam(defaultValue = "0") int page) {
        return mUserManager.getUsers(page);
    }
}

My configurations:
OAuth2Config:

@Configuration
@EnableAuthorizationServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {

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

    @Autowired
    private AppConfig mAppConfig;

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

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.jdbc(mAppConfig.userDataSource())
                .withClient("sampleClientId")
                .authorizedGrantTypes("implicit")
                .scopes("read")
                .autoApprove(true)
                .and()
                .withClient("clientIdPassword")
                .secret("secret")
                .authorizedGrantTypes("password", "authorization_code", "refresh_token")
                .scopes("read");
    }

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

ServerSecurityConfig:

@Configuration
public class ServerSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("[email protected]")
                .password("123@Qwerty")
                .roles("USER");
    }

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().permitAll();
    }
}

P.S. I'm using the Sring Boot 1.5.9.RELEASE

Upvotes: 1

Views: 1133

Answers (2)

Toerktumlare
Toerktumlare

Reputation: 14819

look at your scopes.

The token issued as no scope.

Your method security demands that you haver the scope "read".

Upvotes: 0

Czyhandsome
Czyhandsome

Reputation: 21

Does your spring-security config don't permit access_token url? Probably your configuration requires authority to access the access_token exchange url, and then redirect to the login page.

You can try permitAll() for this url, and try again.

===== Update =====

Is your authorization server in the same project with resource server? If so, it often occurs to me that you can not use token to access the secured URLs. In my case, I have to seperate the resource server and the authorization server into two projects, run them both, then I can access the URL with tokens correctly.

Upvotes: 1

Related Questions