51

I am trying to use spring-security-oauth2.0 with Java based configuration. My configuration is done, but when i deploy application on tomcat and hit the /oauth/token url for access token, Oauth generate the follwoing error:

<oauth>
<error_description>Full authentication is required to access this resource</error_description>
<error>unauthorized</error>
</oauth>

My configuration is on Git hub, please click on link

The code is large, so refer to git. I am using chrome postman client for send request. follwing is my request.

POST /dummy-project-web/oauth/token HTTP/1.1
Host: localhost:8081
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=abc%40gmail.com&client_secret=12345678 

The error is just like, the URL is secure by Oauth, but in configuration, i give the all permission for access this URL. What actual this problem is?

Harmeet Singh Taara
  • 6,483
  • 20
  • 73
  • 126
  • 1
    The error is a spring framework error. Check my answer [here](https://stackoverflow.com/questions/42181318/post-request-full-authentication-is-required-to-access-this-resource/59212833#59212833). – Dejazmach Dec 06 '19 at 12:14

8 Answers8

31

The client_id and client_secret, by default, should go in the Authorization header, not the form-urlencoded body.

  1. Concatenate your client_id and client_secret, with a colon between them: abc@gmail.com:12345678.
  2. Base 64 encode the result: YWJjQGdtYWlsLmNvbToxMjM0NTY3OA==
  3. Set the Authorization header: Authorization: Basic YWJjQGdtYWlsLmNvbToxMjM0NTY3OA==
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
GaryF
  • 23,950
  • 10
  • 60
  • 73
  • 1
    i think, this is used with `grant_type=password` for `client_credentials` there is no need for this. if i am wrong, please correct me. – Harmeet Singh Taara Nov 12 '14 at 10:19
  • 1
    when i try this, the exception will throw `error="invalid_token", error_description="Invalid access token: abc@gmail.com"`. I thin, for access this resource, it required auth token, but why ? – Harmeet Singh Taara Nov 12 '14 at 10:23
  • No, grant_type=password is where the resource owner's user/pass (i.e. the end user) are going to be provided directly to the client. client_credentials is used when you are not authenticating the resource owner at all; just the client itself. That's what your question indicates. Use client_credentials with the scheme I indicate in my answer iff you genuinely do want to just authenticate the client, not the user. – GaryF Nov 12 '14 at 10:33
  • 1
    Thanks @GaryF for your solution, but still this not work, the above error is still generated `error="invalid_token", error_description="Invalid access token: abc@gmail.com" `, what is that problem ? – Harmeet Singh Taara Nov 12 '14 at 10:45
  • i am using `BcryptPasswordEncoder` if i remove this, now the error is change `The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers.` i think this is generate , when response is wrong? – Harmeet Singh Taara Nov 12 '14 at 10:55
  • Thanks @GaryF now its working, i think the problem with `BcryptPasswordEncoder`. – Harmeet Singh Taara Nov 12 '14 at 11:19
  • again thanks for you help, but still i have confusion. When i send Authorization Basic with 64 encoding in header, i will access the token, but after token detail recive, when i access the URL there is not need to send the token in header, just again send the basic authorization. Why this problem occur ? – Harmeet Singh Taara Nov 13 '14 at 18:26
  • can you please help me on this question @maniekq can you please help me on this ques https://stackoverflow.com/questions/48806722/can-i-append-some-information-in-oauth-check-token-endpoint-and-retrieve-it-at-a –  Feb 25 '18 at 19:19
19

By default Spring OAuth requires basic HTTP authentication. If you want to switch it off with Java based configuration, you have to allow form authentication for clients like this:

@Configuration
@EnableAuthorizationServer
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {
  @Override
  public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
    oauthServer.allowFormAuthenticationForClients();
  }
}
jozala
  • 4,625
  • 2
  • 18
  • 15
  • 1
    can you please help me on this ques https://stackoverflow.com/questions/48806722/can-i-append-some-information-in-oauth-check-token-endpoint-and-retrieve-it-at-a –  Feb 25 '18 at 19:18
6

The reason is that by default the /oauth/token endpoint is protected through Basic Access Authentication.

All you need to do is add the Authorization header to your request.

You can easily test it with a tool like curl by issuing the following command:

curl.exe --user abc@gmail.com:12345678 http://localhost:8081/dummy-project-web/oauth/token?grant_type=client_credentials

Marco Lenzo
  • 318
  • 2
  • 8
  • I tried your answer, but then I get a popup to insert username and password. I try with my login and it doesn't help – Dejell Feb 24 '15 at 21:53
1

With Spring OAuth 2.0.7-RELEASE the following command works for me

curl -v -u abc@gmail.com:12345678 -d "grant_type=client_credentials" http://localhost:9999/uaa/oauth/token

It works with Chrome POSTMAN too, just make sure you client and secret in "Basic Auth" tab, set method to "POST" and add grant type in "form data" tab.

Stackee007
  • 3,196
  • 1
  • 26
  • 39
1

You should pre authenticate the token apis "/oauth/token"

extend ResourceServerConfigurerAdapter and override configure function to do this.

eg:

http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests().antMatchers("/oauth/token").permitAll().
anyRequest().authenticated();
Salman Zafar
  • 3,844
  • 5
  • 20
  • 43
1

This is incredible but real.

csrf filter is enabled by default and it actually blocks any POST, PUT or DELETE requests which do not include de csrf token.

Try using a GET instead of POST to confirm that this is it.

If this is so then allow any HTTP method:

@Throws(Exception::class)
override fun configure(http: HttpSecurity) {

    /**
     * Allow POST, PUT or DELETE request
     *
     * NOTE: csrf filter is enabled by default and it actually blocks any POST, PUT or DELETE requests
     * which do not include de csrf token.
     */
    http.csrf().disable()

}

If you are obtaining a 401 the most intuitive thing is to think that in the request you have No Auth or you are missing something in the headers regarding authorization.

But apparently there is an internal function that is filtering the HTTP methods that use POST and returns a 401. After fixing it I thought it was a cache issue with the status code but apparently not.

GL

Braian Coronel
  • 22,105
  • 4
  • 57
  • 62
0

I had the same problem, but I solve this with the following class:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class OAuthSecurityConfiguration extends WebSecurityConfigurerAdapter {

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

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }
}
0

If you have multiple services running on the same proxy server, make sure your proxy is correctly redirecting to servername/oauth/token rather than servername/servicename/oauth/token.

Anton Duzenko
  • 2,366
  • 1
  • 21
  • 26