5 minutes with – Spring OAuth 2.0

What can you use when you’ve to let the access of protected resources by a third part application? The Open Authentication standard (briefly OAuth) is useful in order to authenticate and authorize user credentials from an external application and grant the access of your resources.

The Open Authentication is a standard defined by the RFC (Request For Comments) number 6749 and is used when we’re not in common scenario to be the system application and the system validator and we’ve everything under our control.

We’re in the scenario when the application who consume the resource (consumer) is not the same which hold the information (server). Let me show it by using a graph.

oauth1

The client access to his application (1) and makes the request to be grant to access a protected resource (2). The Authentication Server returns an access token based on the posted user credential (3). Afterward, the user makes the request passing the access token just got by the user (4). Once the token is validated, the Resource Server returns the protected resource to the Client Application (5).

Quite easy, isn’t it? Take a look at sequence diagram to clarify the concept above.

oauth2

 

The client request contains the user and the client credential. We use the “grant_type=password” to send the user credential. The standard accepts four types of grant_type (authorization_code, password, client_credentials and refresh_token); more details are available on reference page.

So, if the Authentication Server validates the credential, it returns the access token composed by the access token itself, the token type, the expires date of the token and the refresh token (we’ll see the use of that later).

Using the access token in the header, we can access the protected resource from the Resource Server.

What happens when the token expires? Well, you get the  message “invalid_token” but we can get another valid token using the refresh_token and changing the “grant_type” in “refresh_token”.

Have a look at the sequence diagram.

oauth3

Once the user get the new access token, the process goes on as normal described in the first diagram.

Now, it’s time to take a look at some code. Before starting I’ve to say that is useful to be familiar with Spring Security to understand all the configuration blocks because Spring OAuth 2.0 is based on Spring Security. We’ve a system with 2 Rest.

The first is for getting and refreshing the access token (/oauth/token). The second is for accessing the protected resource (/protected/userresource/userprofile).

The core of the system is the spring configuration file.


<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
	xmlns:sec="http://www.springframework.org/schema/security" xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
		http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

	<sec:http pattern="/oauth/token" create-session="stateless"
		authentication-manager-ref="authenticationManager">
		<sec:intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
		<sec:anonymous enabled="false" />
		<sec:http-basic entry-point-ref="clientAuthenticationEntryPoint" />
		<sec:custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
		<sec:access-denied-handler ref="oauthAccessDeniedHandler" />
	</sec:http>

    <sec:http pattern="/protected/**" create-session="never"
        entry-point-ref="oauthAuthenticationEntryPoint">
        <sec:anonymous enabled="false" />
        <sec:intercept-url pattern="/protected/**" method="GET" access="IS_AUTHENTICATED_FULLY" />
        <sec:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
        <sec:access-denied-handler ref="oauthAccessDeniedHandler" />
    </sec:http>

	<bean id="oauthAuthenticationEntryPoint"
		class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
	</bean>

	<bean id="clientAuthenticationEntryPoint"
		class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
		<property name="realmName" value="springsec/client" />
		<property name="typeName" value="Basic" />
	</bean>

	<bean id="oauthAccessDeniedHandler"
		class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler">
	</bean>

	<bean id="clientCredentialsTokenEndpointFilter"
		class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
		<property name="authenticationManager" ref="authenticationManager" />
	</bean>

	<sec:authentication-manager alias="authenticationManager">
		<sec:authentication-provider user-service-ref="clientDetailsUserService" />
	</sec:authentication-manager>

	<bean id="clientDetailsUserService"
		class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
		<constructor-arg ref="clientDetails" />
	</bean>

	<bean id="clientDetails" class="it.iol.oauthaaa.security.AAAGuestServiceImpl">
		<property name="id" value="mysupplycompany" />
		<property name="secretKey" value="mycompanykey" />
	</bean>

	<sec:authentication-manager id="userAuthenticationManager">
		<sec:authentication-provider ref="customUserAuthenticationProvider" />
	</sec:authentication-manager>

	<bean id="customUserAuthenticationProvider"
		class="it.iol.oauthaaa.security.AAAUserAuthenticationProvider">
	</bean>

	<oauth:authorization-server
		client-details-service-ref="clientDetails" token-services-ref="tokenServices">
		<oauth:authorization-code />
		<oauth:implicit/>
		<oauth:refresh-token/>
		<oauth:client-credentials />
		<oauth:password authentication-manager-ref="userAuthenticationManager"/>
	</oauth:authorization-server>

	<oauth:resource-server id="resourceServerFilter"
		resource-id="springsec" token-services-ref="tokenServices" />

	<bean id="tokenStore"
		class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />

	<bean id="tokenServices"
		class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
		<property name="tokenStore" ref="tokenStore" />
		<property name="supportRefreshToken" value="true" />
		<property name="accessTokenValiditySeconds" value="120"></property>
		<property name="clientDetailsService" ref="clientDetails" />
	</bean>

	<mvc:annotation-driven />

	<mvc:default-servlet-handler />

	<context:annotation-config/>

	<bean id="MyResource" class="it.iol.oauthaaa.resources.UserResource"></bean>
	<bean id="aaaProxy" class="it.iol.oauthaaa.security.AAAProxy"></bean
</beans>

Once the process has started, the first part invoked is <sec:http pattern=”/oauth/token”.. which, by the filter, extracts the client credential from the data request. Thery’re processed in this code:

@Service
public class AAAGuestServiceImpl implements ClientDetailsService {

	private String id;
	private String secretKey;

	@Override
	public ClientDetails loadClientByClientId(String clientId)
			throws OAuth2Exception {

		if (clientId.equals(id))
		{
			List<String> authorizedGrantTypes = new ArrayList<String>();
			authorizedGrantTypes.add("password");
			authorizedGrantTypes.add("refresh_token");
			authorizedGrantTypes.add("client_credentials");

			BaseClientDetails clientDetails = new BaseClientDetails();
			clientDetails.setClientId(id);
			clientDetails.setClientSecret(secretKey);
			clientDetails.setAuthorizedGrantTypes(authorizedGrantTypes);

			return clientDetails;
		}
		else {
			throw new NoSuchClientException("No client recognized with id: "
					+ clientId);
		}
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getSecretKey() {
		return secretKey;
	}

	public void setSecretKey(String secretKey) {
		this.secretKey = secretKey;
	}

}

Now it’s time to validate the user credential based of username and password (remember the grant_type=password). That happens in the <oauth:authorization-server block by the definition of “userAuthenticationManager”. The code is the following.


public class AAAUserAuthenticationProvider

implements AuthenticationProvider {

	@Autowired
	AAAProxy aaaProxy;

	@Override
	public Authentication authenticate(Authentication authentication)
			throws AuthenticationException {

		boolean result = aaaProxy.isValidUser(authentication.getPrincipal()
				.toString(), authentication.getCredentials().toString());

		if (result) {
			List<GrantedAuthority> grantedAuthorities =

new ArrayList<GrantedAuthority>();
			AAAUserAuthenticationToken auth =

new AAAUserAuthenticationToken(authentication.getPrincipal(),
			authentication.getCredentials(), grantedAuthorities);

			return auth;
		} else {
			throw new BadCredentialsException("Bad User Credentials.");
		}
	}

	public boolean supports(Class<?> arg0) {
		return true;
	}
}

A little note; aaaProxy is the object used to authenticate the user with its credential. It’s not topic of this article describing how it works. If the user is valid, these steps will be completed:

  • The framework will update object in the security context;
  • The TokenServices will generate a new token object (with expire date of 120 seconds);
  • The TokenStore will store the new token generated (stored with InMemoryTokenStore);

Then, the token will be send to the client.

The last codes are the AuthenticationToken and the protected resource:


public class AAAUserAuthenticationToken 

extends AbstractAuthenticationToken {

	private static final long serialVersionUID = -1092219614309982278L;
	private final Object principal;
	private Object credentials;

	public AAAUserAuthenticationToken(Object principal, Object credentials,
			Collection<? extends GrantedAuthority> authorities) {
		super(authorities);
		this.principal = principal;
		this.credentials = credentials;
		super.setAuthenticated(true);
	}

	public Object getCredentials() {
		return this.credentials;
	}

	public Object getPrincipal() {
		return this.principal;
	}
}

The protected resource:

@Path("/userresource")
public class UserResource {

	@GET
	@Path("/userprofile")
	public String getUserProfile(){
		return "Welcome in protected Area. User enabled.";
	}
}

Let’s try to test this code. I used fiddler but, obviously, you can use what you want to make the request (wget, curl, etc…).

The first request:

/OAuthAAA/oauth/token?username=myuser&password=mypassword
&client_id=mysupplycompany&client_secret=mycompanykey&grant_type=password

And produce this output:

oauth4

 

The resource request:

/OAuthAAA/protected/userresource/userprofile
Authorization: Bearer 5cf0732b-6bbb-40c7-8fab-dcfefcc2fcfe

And produce this output:

oauth5

We’ve arrived at the end of the article. My recommendation is to take a look at the document RFC6749. A special thanks to Nitin Gupta for his post “REST Authentication using OAUTH 2.0“.

UPDATE

package it.iol.oauthaaa.security;

import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Proxy.Type;
import java.util.List;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

public class AAAProxy {

	private Proxy proxy;
	private RestTemplate template;

	public AAAProxy() {
		proxy = new Proxy(Type.HTTP, new InetSocketAddress(
				"proxy.abc.net", 3001));

		SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();

		requestFactory.setProxy(proxy);

		template = new RestTemplate(requestFactory);
	}

	public boolean isValidUser(String user, String password) {

		MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
		map.add("user", user);
		map.add("password", password);

		HttpEntity<String> response = template.postForEntity(
				"https://authentication.local/auth", map,
				String.class);

		HttpHeaders headers = response.getHeaders();

		List<String> cookies = headers.get("Set-Cookie");

		for (String cookie : cookies) {
			if (cookie.indexOf("Auth")!=-1)
				return true;
		}

		return false;
	}

}

UPDATE/2
As Shlomi said, another available configuration is using the “client_credentials” in the “grant_type”.
As the diagram shows, the interaction is quite similar to the “password” client credentials.

oauth_client_credentials

Notice that the refresh_token tag is missing in the Json.
The reason is explained in the chapter 4.4.3. “Access Token Response” of the rfc-6749 specification.
“…  A refresh token SHOULD NOT be included…”

83 thoughts on “5 minutes with – Spring OAuth 2.0”

  1. Excellent post Sir. I am a little confuse for one thing; I want to use postgresql database for storing tokens and client credentials. Can you please guide me a little bit about it. It will be very very helpful for me and others novice like me.

    Thanks for the excellent explanation.

    1. Hi Ali,
      If you want to use database storage istead of in memory, you’ve to put org.springframework.security.oauth2.provider.token.JdbcTokenStore as tokenStore and configure the datasource.
      So,


      I use MySql

      The table schemas are the follows:
      CREATE TABLE `oauth_access_token` (
      `token_id` varchar(256) DEFAULT NULL,
      `token` blob,
      `authentication_id` varchar(256) DEFAULT NULL,
      `user_name` varchar(256) DEFAULT NULL,
      `client_id` varchar(256) DEFAULT NULL,
      `authentication` blob,
      `refresh_token` varchar(256) DEFAULT NULL,
      `access_token_validity` int(11) DEFAULT NULL,
      `refresh_token_validity` int(11) DEFAULT NULL
      ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

      and

      CREATE TABLE `oauth_refresh_token` (
      `token_id` varchar(256) DEFAULT NULL,
      `token` blob,
      `authentication` blob
      ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

      1. Dear techannotation,

        Thank you very much for your response. I will create the tables in postgresql and test if it is working or not. If I got stuck in any problem, I will ask your help.
        Once again thank you!

      2. Hi Techannotation Team, Could you please provide me complete source code link? I desperately need the code to understand the Spring OAuth2 concept.

      3. Hi,

        I am very new to OAuth2.0, shall i change the DB table structure fully

        Thanks
        Pravin Kumar

      4. Hi.
        Yes you can although I don’t think it’s a good idea.
        Have a look at org.springframework.security.oauth2.provider.token.JdbcTokenStore class and you’ll see the Spring code for accessing the database.
        The structure of that is described on the article “Spring Oauth2 with Authorization Code” that I wrote in the last June.

    1. Hi Dinesh.
      The only documentation that I’ve found was about MySql Schema.
      Here the reference https://raw.githubusercontent.com/spring-projects/spring-security-oauth/master/spring-security-oauth2/src/test/resources/schema.sql
      I have got an experience with MongoDb but I’ve never used Cassandra.
      The schema is quite easy to move into another database engine; the only trouble could be the “Blog” data type.
      You might have a look at org.springframework.security.oauth2.provider.JdbcClientDetailsService class. This is the class used for storing and getting the stored tokens.

  2. Hi,
    here you’ve used <oauth:password grant type but i wanted to use <oauth:authorization-code grant type so, what are the necessary changes i have to do .

    1. Hi Harsha,
      I’ve used both nodes and not either one.
      According with the documentation:

      oauth:authorization-code
      The configuration of the authorization code mechanism. This mechanism enables a way for clients to obtain an access token by obtaining an authorization code.

      oauth:password
      The configuration of the resource owner password grant type.

  3. Hay, i thought its a great example.
    I finally made it work, but i cant rly pass by the request for the authorization.
    Maybe Im acting dumb, but my first request always gets me an error

    //oauth/token?username=myuser&password=mypassword
    &client_id=mysupplycompany&client_secret=mycompanykey&grant_type=password

    error:
    {“error”:”invalid_scope”,”error_description”:”Empty scope (either the client or the user is not allowed the requested scopes)”}

    I cant rly figure out, where i set up the user. would appreciate a bit of help ;)

  4. I followed the tutorial and now I am getting –
    oauth2ErrorCode: “invalid_scope”
    summary: “error=”invalid_scope”, error_description=”Empty scope (either the client or the user is not allowed the requested scopes)””
    httpErrorCode: 400

    Any help would be appreciated. Thanks.

  5. Hi Khobab,

    I am getting the TOKEN by passing this URL without username and Password also like the following URL,
    http:/localhost:8080/oauth2/oauth/token?grant_type=password&client_id=client1&client_secret=secret1– it is also working fine but user name and password are necessary or not. it we are not giving any username and password then also getting the TOken.

    How can I do Please suggest to me , Thanks In Advance….

    Spring-security.xml

    1. Hi Ravi,
      Username and password are mandatory whether the user isn’t still authenticated in the WebApp (Principal Empty).
      So, the url
      /OAuthAAA/oauth/token?username=user@alice.it&password=pwd&client_id=mysupplycompany&client_secret=mycompanykey&grant_type=password
      Lets the user to access the protected resource using their credentials.

      1. I have seen sample example also but User name and passwords are not validating in that example also.
        I am not able to fix that problem please suggest to me ..

        Thanks in Advance..

      2. Hi Ravi,
        The user is validated in the AAAProxy class with the method isValidUser(String user, String password).

        I used an external resource to validate it.
        Hope to help you.

  6. Hi , as others has mentioned the user/pass are not required – this is the whole point of client_credentials flow (not password flow)
    as i see in the code , spring is able to authenticate the user with only client_id and client_secret.
    the whole point here is that clients will not need to save the password.
    i also have a working example with client_credentials grant type which does not require user/pass.
    Shlomi

    1. Hi Shlomi.
      I agree with you, it’s possible to use Open Authentication without send the user credentials. According with the url “/oauth/authorize”, the user must be already authenticated in Spring to perform that url:
      ..
      if (!(principal instanceof Authentication) || !((Authentication) principal).isAuthenticated()) {
      throw new InsufficientAuthenticationException(“User must be authenticated with Spring Security before authorization can be completed.”);
      }
      ..
      If you’re speaking about something different, please, let me see the example in order to understand the issue.
      Thanks.

      1. I think we are talking about 2 different grant types and endpoints. i’m talking about crendentials_flow , to get a token user request this URL for example,

        http://localhost:8080/agm/auth/oauth/token?client_id=my-trusted-client&client_secret=secret&grant_type=client_credentials

        notice there is no password, there is something else which is the secret, but this is OK, although the same this protects us from integrations where the user decide to change his password (the secret is not changing)
        hope its clearer

        Shlomi

      2. Hi Shlomi.
        Thanks for your reply. Now, I’ve got the meaning of the discussion.
        You’ve sent a valid method to obtain a token for the user.
        Thank you again for your comment, I hope to get the time to write the same example with this method.

  7. Apologies. I’m getting the error on the very first step:

    /OAuthAAA/oauth/token?username=myuser&password=mypassword
    &client_id=mysupplycompany&client_secret=mycompanykey&grant_type=password

    Thanks

    1. Hi,

      It seems that the no one authentication object has been set in the SecurityContext.
      This is set in the AuthenticationProvider class evaluating the “isValidUser” method result.
      How did you implemented the AAAProxy class? Are you always getting true from the “isValidUser” method? Can you check the value of authentication.getPrincipal()?

      I used Spring version 3.1.0.

  8. Hello,
    Thank you for the quick response!
    Unfortunately, the execution doesn’t look to be getting far enough to invoke the user provided code.

    I’m sending the message below from curl.

    /oauth/token?username=myuser&password=mypassword&client_id=mysupplycompany&client_secret=mycompanykey&grant_type=password

    Below is the debug trace from the url match to the exception. I haven’t traced an OAuth2 token request before so I don’t know if it’s normal for the query string to get cutoff after “username=myuser” for logging purposes.

    DEBUG: org.springframework.security.web.util.AntPathRequestMatcher – Checking match of request : ‘/oauth/token’; against ‘/oauth/token’
    DEBUG: org.springframework.security.web.access.intercept.FilterSecurityInterceptor – Secure object: FilterInvocation: URL: /oauth/token?username=myuser; Attributes: [IS_AUTHENTICATED_FULLY]
    DEBUG: org.springframework.security.web.access.ExceptionTranslationFilter – Authentication exception occurred; redirecting to authentication entry point
    org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext

    I am able to invoke the /userresource/userprofile url and invoke the getUserProfileMethod()

    Any thoughts or insights would be appreciated

    thanks

  9. OK – brain freeze. I’m using a different REST tester and getting different results. Something to do with curl truncating the query string. I’ll work thru it some more.

    Thanks again for the reply.

  10. Hello,
    Unfortunately, I’m unable to get the sequence from access token to protected resource

    I’m getting the response from the password code grant below:
    Request

    /oauth/token?username=myuser&password=mypassword&client_id=mysupplycompany&client_secret=mycompanykey&grant_type=password

    Response
    {
    value: “06c707f1-2867-4b07-85ed-e4a6e86106c0”
    expiration: 1421339044500
    tokenType: “bearer”
    refreshToken: {
    value: “38d235ed-8aa3-4151-b2f9-f61945baf4d2”
    expiration: 1423927715558
    }-
    scope: [0]
    additionalInformation: {}
    expired: false
    expiresIn: 120
    }

    Then using the value field as the access token

    Request

    /protected/userresource/userprofile
    Authorization: Bearer 06c707f1-2867-4b07-85ed-e4a6e86106c0

    Response

    oauth2ErrorCode: “invalid_token”
    httpErrorCode: 401
    summary: “error=”invalid_token”, error_description=”Invalid access token: 06c707f1-2867-4b07-85ed-e4a6e86106c0″”
    message: “Invalid access token: 06c707f1-2867-4b07-85ed-e4a6e86106c0”
    localizedMessage: “Invalid access token: 06c707f1-2867-4b07-85ed-e4a6e86106c0”

    The token store is configured as in the post

    any thoughts?

    Thanks

    1. Any chance this is clustered environment , the only thing i can think of is the token generated on one node and not recognized by the other.
      i don’t really understand why people will use the password flow – what difference does it make from just authenticating and getting the data.

  11. i have one question regarding existing valid token.How we can alter the existing valid token expiry time,when we do request the protected URL.

    1. Hi Mishra,
      The value of the token validity time is stored in the class org.springframework.security.oauth2.provider.token.InMemoryTokenStore.
      Honestly, I don’t recommend to change this value but using the refresh-token to obtain a new valid token.

    1. Hi Guys,

      To everyone who ask me about the source code I’m really sorry but I cannot share the complete source code due to copyright limitations.

      The code has been developed for a customer and the snippet in the article is only an extraction of a complete solution.

      I hope you may understand the issue. Thanks for reading the article.

      Marco

      1. Hi, Please can you try to create sample prototype based on your current example with all class names changed or with some minor changes? I’d really help the followers of your blogs.

  12. I’m trying to use latest maven dependency for and updating .xml file

    org.springframework.security.oauth
    spring-security-oauth2
    2.0.6.RELEASE

    But I’m getting following error:
    Multiple annotations found at this line:
    – No setter found for property ‘tokenServices’ in class
    ‘org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler’ [config set: mp-oauth2rest/web-context]
    – No setter found for property ‘tokenServices’ in class ‘org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler’

    The following line causing the exception:

    1. Hi,

      It seems that the setter ‘tokenServices’ has been changed as ‘tokenStore’ (I’ve looked at the source code at 2.0.6 version).

      Unfortunately, the solution doesn’t work with this version (some methods are missing).

      As soon as I’ll be able to work on it, I’ll try to change the code in order to move that to the last version.

      1. Hi, Could you please share a GIT code repository link? Even its getting difficult to understand your awesome example fully. Please help.

      2. Hello, I’m trying something interesting like xml configuration for Mongo (NoSql database) instead for the MySql, but somehow I don’t find way for it/ Please help us !

      3. Hi,
        I haven’t got any experience with Oauth and MongoDb but, looking the configuration code, I think you need to complete 2 steps:
        – Change the “jdbcTemplate” bean using the MongoDb driver
        – Writing your MongoDbTokenStore Implementing the interface “org.springframework.security.oauth2.provider.token.TokenStore” writing the methods to access MongoDb.

  13. Hi!
    Thank you for sharing this example it’s really nice and comprehensible but I still have more questions.
    In my case, I have a web application (let’s say http://www.myapp.com and the login page is external (for example http://www.login.com/auth), I mean, when you try to log into a protected resource and you are not authenticated, you should be redirected to http://www.login.com/auth, perform the login/pass logic and then return a code to the main app (www.myapp.com). Then, with the code you have to go back to the login app (www.login.com/access_token) and retrieve the access token. After a successful process, you have to be authenticated into the webpage.
    The problem is that I have no clue on where to start or where to config this redirection/authentication/etc.

    Maybe you can help me with a related example or something like that because I’m completely lost.

    Thanks a lot!

    1. Hi,
      Thanks for your comment. I’m working on a better example to illustrate the process but, unfortunately, I still haven’t got enough time to write an article.

      In the meantime, I suggest you to have a look at the url:
      http://localhost.:8080/OAuthAAA/oauth/authorize?response_type=code&client_id=mysupplycompany&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2FOAuthAAA%2Findex.jsp

      and

      http://localhost.:8080/OAuthAAA/oauth/token?grant_type=authorization_code&code=qhF9YS&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2FOAuthAAA%2Findex.jsp

      The first one gives you the code to get a token (after authorize the application) while the last gives you the request token (remember to replace the code in the request with which you obtain from the first request.

      I know it’s not a big clue but that’s it.
      I’m looking forward to writing the article.

      1. I will have a look at what you say and try to go forward while waiting for that article ;)

        Thanks again!!!

      2. Hmmm… I think I answered too fast :P
        I know the URLs, but the problem I have is that I do not know how to redirect to them when trying to access to a protected resource.
        Another question I would like to ask (due to my lack of knowledge), what I asked is a CAS implementation?

        Thanks!

  14. Hi Technovation, You inspired me a lot about Spring OAuth2, I’m giving attempt to create the Spring OAuth2 project but when trying to run the following commands, I don’t get expected output. Could you please help me and suggest me where I’m making wrong?
    I’ve place my code here: https://github.com/test512/spring-oauth2

  15. Hi Technovation, this an excelent example about OAuth2, I tried to follow all the code, but when I try to get the toke I get “Error 404 – NotFound”. I’m working in a WebLogic 12c server (12.1.3). I debugged to try to see what’s happen but no success yet. Do you have any ideas about it?

    1. Hi,
      It sounds very strange. Are you sure you’ve put the correct request url with all the parameters? The correct one is /OAuthAAA/oauth/token with http GET method.
      I don’t think the WebServer (or application server) is an issue.

      Check the Http method, maybe it’s requested by POST.
      I hope it can help you.

  16. Hi Techannotation.. Thank you for sharing this example… do you know why my json response was not return as your example but like these :
    {
    “value”: “35bc9da1-0c21-4871-a93d-a3b4929f330a”,
    “expiration”: 1431478837304,
    “tokenType”: “bearer”,
    “refreshToken”: {
    “value”: “9c4d7a53-201a-48cf-86cf-08f1386b7056”,
    “expiration”: 1434070717302
    },
    “scope”: [],
    “additionalInformation”: {
    },
    “expired”: false,
    “expiresIn”: 119
    }
    Thank you.

    1. Hi Tommy.
      I’m using this artifact for Oauth2 implementation.

      <dependency>
      <groupId>org.springframework.security.oauth</groupId>
      <artifactId>spring-security-oauth2</artifactId>
      <version>1.0.5.RELEASE</version>
      </dependency>

      Are we using the same release version?

    1. Hi Kumar,
      1. I think you can put the access token in payload but you need to write a custom security filter to get the value. You can get some examples in this post
      http://stackoverflow.com/questions/15466021/custom-http-authorization-header-with-spring-security

      2. Spring security reads, by default, the Authorization Header for checking the user’s authorization. In Oauth2 Specification the access token is read by check that header. I’d use this instead of using a different security layer, but I don’t know your use case.

      1. I have 2 scenarios where i want to implement the authentication:
        1. I want to implement access token authentication when a user logs in. i.e.. based on username and password , user should get a token and that token should be used with every request.
        2. I have a separate independent module which has ID and secret Key. It has to communicate with server in specific interval. I want to implement token based authentication for this module.

        In both the cases token should have these properties:
        1. It should be in payload.
        2. It should have a timeout period also.
        3. When token expires server should provide a new token.If the session is not expired else it should logout.
        4. Token should stay in payload not in header.

        What should I do?
        Is OAuth 2.0 is the right choice?

      2. Well, I think OAuth2 is a good approach for your problem. It provides the mechanisms of authorization code and authentication token, so, I don’t see any reason for saying that’s not the right choice.

        Having said that, I think you need to write your custom security filter in order to check the authentication value in the Payload. Honestly, I’ve never done something similar before, but I find a lot of example on google, so, it’s not so rare use case.

        Good luck!

  17. Hi Techannotation,
    I have Question regarding Clustered environment.
    Lets suppose my cluster has two nodes Node1 and Node2.
    How can i generate an access_token which is valid for both the nodes?
    Currently in my implementaion, the access_token is valid to only that particular node and for the other it throws “invalid access token”

  18. Hi Techannotation,
    How to make a access_token valid for all the nodes in a clustered environment.
    lets suppose i have a load balancer on top of my weblogic cluster and in such cases request can go to any node in the cluster. how to configure the OAUTH to share the same access_token across the cluster.

    Thank You

    1. Hi Neo,
      You can use the JdbcTokenStore instead of InMemoryTokenStore to get the token shared between the two instances.

      <!– <bean id=”tokenStore” class=”org.springframework.security.oauth2.provider.token.InMemoryTokenStore” /> –>
      <bean class=”org.springframework.security.oauth2.provider.token.JdbcTokenStore” id=”tokenStore”>
      <constructor-arg ref=”jdbcTemplate”/>
      </bean>

      <bean class=”org.springframework.jdbc.datasource.DriverManagerDataSource” id=”jdbcTemplate”>
      <property value=”com.mysql.jdbc.Driver” name=”driverClassName”/>
      <property value=”jdbc:mysql://localhost:3306/oauthdb” name=”url”/>
      <property value=”root” name=”username”/>
      <property value=”” name=”password”/>
      </bean>

      You can find more details about the Sql Schema on my post on “Oauth2 with Authorization Code”.

      I hope that it can help you.You can find more details about the Sql Schema on my post on “Oauth2 with Authorization Code”.

      I hope that it can help you.

  19. Hi Marco,

    I found your article very useful (I spent days digging simple examples using OAuth2 before.)
    So I feel I’m almost there where I want. One thing does not work for me.
    When I try to get the token after clientDetailsUserService the authorization never performed (userAuthenticationManager).
    Instead of I get err 404. However I use Spring 4 tried with 3.2 with no success.
    Could you please point to what’s wrong ?

    TIA., Sandor

    —————————————————————————————————

    <!– –>

    1. Hi Sfeher. Thanks for your feedback.

      Are you saying that calling the url /<webapp>/oauth/token?username=myuser&password=mypassword
      &client_id=mysupplycompany&client_secret=mycompanykey&grant_type=password you’re receiving an http 404 message?
      Are you sure that you haven’t any previous error when you deploy this WebApp? It sounds like your webapp is not correctly deployed.

  20. Hi Marco,

    Thank you very much for your article.
    I was following your blog post, but when I perform the following request to my REST API:
    url –user clientapp:secret –data “grant_type=password” –trace-ascii /dev/stdout http://localhost:8080/api/oauth/token

    I receive the following error:
    {“error”:”unauthorized”,”error_description”:”There is no client authentication. Try adding an appropriate authentication filter.”}

    Here is a part of server log:
    Oct 09, 2015 5:44:12 PM org.springframework.security.oauth2.provider.endpoint.TokenEndpoint handleException
    INFO: Handling error: InsufficientAuthenticationException, There is no client authentication. Try adding an appropriate authentication filter.

    Do you know why this can happen?

    1. I’ve tried to execute a GET request, but I’ve received 405:
      curl –trace-ascii /dev/stdout ‘http://localhost:8080/api/oauth/token?username=username&password=password&client_id=clientid&client_secret=secret’

      Error 405 Request method ‘GET’ not supported

      HTTP ERROR 405
      Problem accessing /api/oauth/token. Reason:

          Request method 'GET' not supported

      Powered by Jetty://

      1. Hi Ivan.
        I used the Spring security Outh2 version 1.0.5.
        In that release the GET method was supported.
        @RequestMapping(value = “/oauth/token”)
        public class TokenEndpoint extends AbstractEndpoint {

        Reading deeper the Rfc specification, I check that correct method for calling this method is POST (chapter 2.3.1) and the last Spring Security Oauth2 implements this specification
        @RequestMapping(value = “/oauth/token”, method=RequestMethod.GET)
        public ResponseEntity getAccessToken(Principal principal, @RequestParam
        Map parameters) throws HttpRequestMethodNotSupportedException {
        if (!allowedRequestMethods.contains(HttpMethod.GET)) {
        throw new HttpRequestMethodNotSupportedException(“GET”);
        }
        return postAccessToken(principal, parameters);
        }

        @RequestMapping(value = “/oauth/token”, method=RequestMethod.POST)
        public ResponseEntity postAccessToken(Principal principal

        To answer your question you could change the version with the older 1.0.5, otherwise you must change the calling way of the method.

        Just remind you that I developed and tested the application with the older version.

    2. Hi Ivan.
      I’ve had a look at your URL and I think that something is unexpected. The “username” request parameter is missing.
      Have a look at the url:
      /OAuthAAA/oauth/token?username=myuser&password=mypassword
      &client_id=mysupplycompany&client_secret=mycompanykey&grant_type=password
      Your request doesn’t match with all the parameters.

  21. Hi Macro,

    How to set Scope for the specific OAuth token:

    I am getting response like :

    {
    “value”: “9f6bdef1-eda9-4954-be13-0ff8b51ac5fa”,
    “expiration”: 1448400784614,
    “tokenType”: “bearer”,
    “refreshToken”: {
    “value”: “c8724205-8399-4c21-942f-8fe87d8263ed”,
    “expiration”: 1450692783167
    },
    “scope”: [],
    “additionalInformation”: {},
    “expiresIn”: 299999,
    “expired”: false
    }

      1. Hi Macro,

        Let me tell you my requirement clearly :

        suppose i am having 4 protected resource as follow :

        /test/pull
        /test/push
        /test1/pull
        /test1/pull

        Base url is same for every resource

        let’s say i am having 2 client, for one client only want to give access for first two resource and for another client last two resource

        can plz help me to do this

        i am waiting for your reply, reply me as soon as possible

        Thanks

      2. Hi Pravin.
        Honestly, I have never use the scope parameter in my project. I’d make some test but I’ve no time to get the solution.
        Nonetheless, I’d like to give you this suggestion (or, at least, where I’d begin..).
        Have a look at node, I think you should build another filter for checking the scope value.
        The ResourceServerBeanDefinitionParser bean is the class that check the security resource. Try to debug this class.
        I know these are poor suggestions, anyway I hope that can they can help you.

  22. Hi Macro,

    I created the project follow your steps, but AAAUserAuthenticationProvider never called. I don’t know Why? and How?, could you please help to explained.

    1. Hi Keesh.
      Check the customUserAuthenticationProvider bean. The class AAAUserAuthenticationProvider is called inside the bean and then used in the Authentication Manager.

  23. Multiple markers at this line
    – Authentication cannot be resolved
    to a type
    – Authentication cannot be resolved
    to a type
    Am using springs 4.2.3

    1. Hi Kumar.
      This code has been built using Spring version 3.x.
      I noticed the difference with the earlier version but I still haven’t got the time to update the version.

  24. Access is denied
    access_denied

    Control is going till “return clientDetails;” of loadClientByClientId method, but not to AAAUserAuthenticationProvider class

Leave a reply to rz9pn9 Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.