John
John

Reputation: 63

Spring OAuth 2 Call /oauth/token Resulted in 401 (Unauthorized)

Greeting everyone, I try to configure simple authorization code flow via Spring Security OAuth.

I tested my authorisation and resource server configuration via following approaches:

  1. Create a web application as client and use its page to fire http post call to /oauth/authorize.
  2. After getting code, I use the same page to fire another http post with code and get token.
  3. At the end, I use curl -H to place token inside header and get response from protected resource.

But when I try to use rest template. It throw error message 401 Unauthorised error.

Server side - security configure:

<http auto-config="true" pattern="/protected/**"
    authentication-manager-ref="authenticationManager">
    <custom-filter ref="resourceFilter" before="PRE_AUTH_FILTER" />
    <csrf disabled="true" />
</http>

<http auto-config="true">
    <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
    <form-login default-target-url="/admin.html" />
    <logout logout-success-url="/welcome.html" logout-url="/logout"/>
    <csrf disabled="true" />
</http>

<authentication-manager alias="authenticationManager">
    <authentication-provider>
        <user-service>
            <user name="admin" password="123456" authorities="ROLE_USER,ROLE_ADMIN" />
        </user-service>
    </authentication-provider>
</authentication-manager>

Server side - authorisation and resource configure:

<oauth:authorization-server
    client-details-service-ref="clientDetails" error-page="error">
    <oauth:authorization-code />
</oauth:authorization-server>

<oauth:client-details-service id="clientDetails">
    <oauth:client client-id="admin" secret="fooSecret" />
</oauth:client-details-service>

<oauth:resource-server id="resourceFilter" />

Client Side:

<oauth:client id="oauth2ClientContextFilter" />
<oauth:resource id="sso" client-id="admin"
    access-token-uri="http://localhost:8080/tough/oauth/token"
    user-authorization-uri="http://localhost:8080/tough/oauth/authorize"
    use-current-uri="true" client-secret="secret"
    client-authentication-scheme="header" type="authorization_code"
    scope="trust" />
<oauth:rest-template id="template" resource="sso"/>

If anyone knows where goes wrong, please do let me know.

Upvotes: 3

Views: 11710

Answers (2)

John
John

Reputation: 63

There were two issues with my configuration above.

  1. I noticed my client used wrong secret to communicate with authorization server.
  2. Token endpoint at authorization server use authentication manager which serve user authentication. It result client are rejected all times until I create new security realm for token endpoint and configure it to use a authentication manger designed for client.

Note client is different from user. Client is third party want to access resource belong to your user (also called resource owner).

Upvotes: 1

siddhartino
siddhartino

Reputation: 359

I had the same problem. It helped to add a

    org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService 

to spring securities authentication-manager, glueing the clientDetailsService to the authentication manager. So

    <authentication-manager alias="authenticationManager">
      ...
      <authentication-provider user-service-ref="clientDetailsUserDetailsService"/>
      ...
    </authentication-manager>

nearly solved the problem for me. I had one more Issue: Since ClientDetailsUserDetailsService has no default constructor, spring threw Exceptions of the form

    org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class
    [class org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService]:
    Common causes of this problem include using a final class or a non-visible class;
    nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given

Which I could not solve without using a copy of that class receiving the clientDetailsService as property instead of a constructor arg.

Upvotes: 0

Related Questions