Secure Spring REST API using OAuth2

Let’s secure our Spring REST API using OAuth2 this time, a simple guide showing what is required to secure a REST API using Spring OAuth2. Our use-case fits well with Resource-owner Password Grant flow of OAUth2 specification. We will use two different clients [Postman and a Spring RestTemplate based java application] to access our OAuth2 protected REST resources.

If you are already familiar with OAuth2 concepts, you may want to skip the theory, and jump right into code. As always, complete code can be found in attachment at the end of this article. Let’s get started.


What is OAuth2

OAuth2 is an standardized authorization protocol/framework. As per Official OAuth2 Specification:

The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf.

Big players like Google, Facebook and others are already using their own OAuth2 implementations for quite some time. Enterprises too are moving fast towards OAuth2 adoption.

I found OAuth2 specification rather simple to follow. Yet if you want to start even quickly, an excellent article on OAuth2 fundamentals can be found here which gives a deep insight in OAUth2 theoretical concepts.

Spring Security OAuth project provides all the necessary API we might need in order to develop an OAuth2 compliant implementation using Spring. Official Spring security oauth project provides a comprehensive example for implementing OAuth2. The code samples of this post is inspired by that examples itself. The intention of this post is to just use bare-minimum functionality required in order to secure our REST API, nothing more.

At minimum, you should be aware of four key concepts in OAuth2:

1. OAuth2 Roles

OAuth2 defines four roles:

  • resource owner:
    Could be you. An entity capable of granting access to a protected resource. When the resource owner is a person, it is referred to as an end-user.
  • resource server:
    The server hosting the protected resources, capable of accepting and responding to protected resource requests using access tokens.
  • client:
    An application making protected resource requests on behalf of the resource owner and with its authorization. It could be a mobile app asking your permission to access your Facebook feeds, a REST client trying to access REST API, a web site [Stackoverflow e.g.] providing an alternative login option using Facebook account.
  • authorization server:
    The server issuing access tokens to the client after successfully authenticating the resource owner and obtaining authorization.

In our example, our REST API can only be accessed via Resource server which will require an access token to be present with request

2. OAuth2 Authorization Grant types

An authorization grant is a credential representing the resource owner’s authorization (to access its protected resources) used by the client to obtain an access token. The specification defines four grant types:

  • authorization code
  • implicit
  • resource owner password credentials
  • client credentials

We will be using resource owner password credentials grant type. The reason is simple, we are not implementing a view which redirects us to a login page. Only the usage where a client [Postman or RestTemplate based Java client e.g.] have the Resource owner’s credentials and they provide those credential [along with client credentials] to authorization server in order to eventually receive the access-token[and optionally refresh token], and then use that token to actually access the resources.

A common example is the GMail app [a client] on your smartphone which takes your credentials and use them to connect to GMail servers. It also shows that ‘Password Credentials Grant’ is best suited when both the client and the servers are from same company as the trust is there, you don’t want to provide your credentials to a third party.

3. OAuth2 Tokens

Tokens are implementation specific random strings, generated by the authorization server and are issued when the client requests them.

  • Access Token : Sent with each request, usually valid for a very short life time [an hour e.g.]
  • Refresh Token : Mainly used to get a new access token, not sent with each request, usually lives longer than access token.
A Word on HTTPS : For any sort of Security implementation, ranging from Basic authentication to a full fledged OAuth2 implementation, HTTPS is a must have. Without HTTPS, no matter what your implementation is, security is vulnerable to be compromised.

4. OAuth2 Access Token Scope

Client can ask for the resource with specific access rights using scope [want to access feeds & photos of this users facebook account], and authorization server in turn return scope showing what access rights were actually granted to the client [Resource owner only allowed feeds access, no photos e.g.].


Let’s Get into Code

Let’s implement the necessary building blocks to implement OAuth using Spring Security, in order to access our REST resources.

1. Resource Server

Resource Server hosts the resources [our REST API] the client is interested in. Resources are located on /user/. @EnableResourceServer annotation, applied on OAuth2 Resource Servers, enables a Spring Security filter that authenticates requests using an incoming OAuth2 token. Class ResourceServerConfigurerAdapter implements ResourceServerConfigurer providing methods to adjust the access rules and paths that are protected by OAuth2 security.

package com.websystique.springmvc.security;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;

@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

	private static final String RESOURCE_ID = "my_rest_api";
	
	@Override
	public void configure(ResourceServerSecurityConfigurer resources) {
		resources.resourceId(RESOURCE_ID).stateless(false);
	}

	@Override
	public void configure(HttpSecurity http) throws Exception {
		http.
		anonymous().disable()
		.requestMatchers().antMatchers("/user/**")
		.and().authorizeRequests()
		.antMatchers("/user/**").access("hasRole('ADMIN')")
		.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
	}

}

2. Authorization Server

Authorization server is the one responsible for verifying credentials and if credentials are OK, providing the tokens[refresh-token as well as access-token]. It also contains information about registered clients and possible access scopes and grant types. The token store is used to store the token. We will be using an in-memory token store.@EnableAuthorizationServer enables an Authorization Server (i.e. an AuthorizationEndpoint and a TokenEndpoint) in the current application context. Class AuthorizationServerConfigurerAdapter implements AuthorizationServerConfigurer which provides all the necessary methods to configure an Authorization server.

package com.websystique.springmvc.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
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.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
import org.springframework.security.oauth2.provider.token.TokenStore;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

	private static String REALM="MY_OAUTH_REALM";
	
	@Autowired
	private TokenStore tokenStore;

	@Autowired
	private UserApprovalHandler userApprovalHandler;

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

	@Override
	public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

		clients.inMemory()
	        .withClient("my-trusted-client")
            .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
            .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
            .scopes("read", "write", "trust")
            .secret("secret")
            .accessTokenValiditySeconds(120).//Access token is only valid for 2 minutes.
            refreshTokenValiditySeconds(600);//Refresh token is only valid for 10 minutes.
	}

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

	@Override
	public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
		oauthServer.realm(REALM+"/client");
	}

}

Above configuration

  • Registers a client with client-id ‘my-trusted-client’ and password ‘secret’ and roles & scope he is allowed for.
  • Specifies that any generated access token will be valid for only 120 seconds
  • Specifies that any generated refresh token will be valid for only 600 seconds

3. Security Configuration

Gluing everything together. Endpoint /oauth/token is used to request a token [access or refresh]. Resource owners [bill,bob] are configured here itself.

package com.websystique.springmvc.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.approval.ApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;

@Configuration
@EnableWebSecurity
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {

	@Autowired
	private ClientDetailsService clientDetailsService;
	
	@Autowired
    public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
        .withUser("bill").password("abc123").roles("ADMIN").and()
        .withUser("bob").password("abc123").roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
		http
		.csrf().disable()
		.anonymous().disable()
	  	.authorizeRequests()
	  	.antMatchers("/oauth/token").permitAll();
    }

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


	@Bean
	public TokenStore tokenStore() {
		return new InMemoryTokenStore();
	}

	@Bean
	@Autowired
	public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore){
		TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
		handler.setTokenStore(tokenStore);
		handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
		handler.setClientDetailsService(clientDetailsService);
		return handler;
	}
	
	@Bean
	@Autowired
	public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
		TokenApprovalStore store = new TokenApprovalStore();
		store.setTokenStore(tokenStore);
		return store;
	}
	
}

Additionally, enable Global method security which will activate @PreFilter, @PostFilter, @PreAuthorize @PostAuthorize annotations if we want to use them.

package com.websystique.springmvc.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler;

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
	@Autowired
	private OAuth2SecurityConfiguration securityConfig;

	@Override
	protected MethodSecurityExpressionHandler createExpressionHandler() {
		return new OAuth2MethodSecurityExpressionHandler();
	}
}

4. Endpoints and their purpose

  • Attempt to access resources [REST API] without any authorization [will fail of-course].
    GET http://localhost:8080/SpringSecurityOAuth2Example/user/
  • Ask for tokens[access+refresh] using HTTP POST on /oauth/token, with grant_type=password,and resource owners credentials as req-params. Additionally, send client credentials in Authorization header.

    POST http://localhost:8080/SpringSecurityOAuth2Example/oauth/token?grant_type=password&username=bill&password=abc123

  • Ask for a new access token via valid refresh-token, using HTTP POST on /oauth/token, with grant_type=refresh_token,and sending actual refresh token. Additionally, send client credentials in Authorization header.

    POST http://localhost:8080/SpringSecurityOAuth2Example/oauth/token?grant_type=refresh_token&refresh_token=094b7d23-973f-4cc1-83ad-8ffd43de1845

  • Access the resource by providing an access token using access_token query param with request.
    GET http://localhost:8080/SpringSecurityOAuth2Example/user/?access_token=3525d0e4-d881-49e7-9f91-bcfd18259109

5. Rest API

The simple Spring REST API i used in most of my posts.

package com.websystique.springmvc.controller;
 
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
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.RestController;
import org.springframework.web.util.UriComponentsBuilder;
 
import com.websystique.springmvc.model.User;
import com.websystique.springmvc.service.UserService;
 
@RestController
public class HelloWorldRestController {
 
    @Autowired
    UserService userService;  //Service which will do all data retrieval/manipulation work
 
     
    //-------------------Retrieve All Users--------------------------------------------------------
     
    @RequestMapping(value = "/user/", method = RequestMethod.GET)
    public ResponseEntity<List<User>> listAllUsers() {
        List<User> users = userService.findAllUsers();
        if(users.isEmpty()){
            return new ResponseEntity<List<User>>(HttpStatus.NO_CONTENT);//You many decide to return HttpStatus.NOT_FOUND
        }
        return new ResponseEntity<List<User>>(users, HttpStatus.OK);
    }
 
 
    //-------------------Retrieve Single User--------------------------------------------------------
     
    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE,MediaType.APPLICATION_XML_VALUE})
    public ResponseEntity<User> getUser(@PathVariable("id") long id) {
        System.out.println("Fetching User with id " + id);
        User user = userService.findById(id);
        if (user == null) {
            System.out.println("User with id " + id + " not found");
            return new ResponseEntity<User>(HttpStatus.NOT_FOUND);
        }
        return new ResponseEntity<User>(user, HttpStatus.OK);
    }
 
     
     
    //-------------------Create a User--------------------------------------------------------
     
    @RequestMapping(value = "/user/", method = RequestMethod.POST)
    public ResponseEntity<Void> createUser(@RequestBody User user, UriComponentsBuilder ucBuilder) {
        System.out.println("Creating User " + user.getName());
 
        if (userService.isUserExist(user)) {
            System.out.println("A User with name " + user.getName() + " already exist");
            return new ResponseEntity<Void>(HttpStatus.CONFLICT);
        }
 
        userService.saveUser(user);
 
        HttpHeaders headers = new HttpHeaders();
        headers.setLocation(ucBuilder.path("/user/{id}").buildAndExpand(user.getId()).toUri());
        return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
    }
 
     
    //------------------- Update a User --------------------------------------------------------
     
    @RequestMapping(value = "/user/{id}", method = RequestMethod.PUT)
    public ResponseEntity<User> updateUser(@PathVariable("id") long id, @RequestBody User user) {
        System.out.println("Updating User " + id);
         
        User currentUser = userService.findById(id);
         
        if (currentUser==null) {
            System.out.println("User with id " + id + " not found");
            return new ResponseEntity<User>(HttpStatus.NOT_FOUND);
        }
 
        currentUser.setName(user.getName());
        currentUser.setAge(user.getAge());
        currentUser.setSalary(user.getSalary());
         
        userService.updateUser(currentUser);
        return new ResponseEntity<User>(currentUser, HttpStatus.OK);
    }
 
    //------------------- Delete a User --------------------------------------------------------
     
    @RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
    public ResponseEntity<User> deleteUser(@PathVariable("id") long id) {
        System.out.println("Fetching & Deleting User with id " + id);
 
        User user = userService.findById(id);
        if (user == null) {
            System.out.println("Unable to delete. User with id " + id + " not found");
            return new ResponseEntity<User>(HttpStatus.NOT_FOUND);
        }
 
        userService.deleteUserById(id);
        return new ResponseEntity<User>(HttpStatus.NO_CONTENT);
    }
 
     
    //------------------- Delete All Users --------------------------------------------------------
     
    @RequestMapping(value = "/user/", method = RequestMethod.DELETE)
    public ResponseEntity<User> deleteAllUsers() {
        System.out.println("Deleting All Users");
 
        userService.deleteAllUsers();
        return new ResponseEntity<User>(HttpStatus.NO_CONTENT);
    }
 
}

6. Running the application

Run it and test it using two different clients.

Client 1: Postman

Try to access a resource without any auth info, wil get a 401.

SpringOAuth2_img1

Let’s get the tokens. First add an authorization header with client credentials [my-trusted-client/secret].

SpringOAuth2_img2

Click on update request, verify the header in header-tab.

SpringOAuth2_img3

Send the Post request, you should receive the response containing access-token as well as refresh-token.

SpringOAuth2_img4

Save these tokens somewhere, you will need them. Now you can use this access-token [valid for 2 minutes] to access resources.

SpringOAuth2_img5

After 2 minutes, access-token gets expired, your further resource requests will fail.

SpringOAuth2_img6

We need a new access-token. Fire a post to with refresh-token to get a brand-new access-token.

SpringOAuth2_img7

Use this new access-token to access the resources.

SpringOAuth2_img8

Refresh-token expires too[10 minutes]. After that, you should see your refresh request getting failed.

SpringOAuth2_img9

It means you need to request a new refresh+access-token, as in step 2.

Client 2: RestTemplate based java application

Method sendTokenRequest is used to actually get the tokens. The access-token we got in response is then used with each request. If required, You can implement the refresh-token flow easily in below example.

package com.websystique.springmvc;
 
import java.net.URI;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;

import org.apache.commons.codec.binary.Base64;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.web.client.RestTemplate;

import com.websystique.springmvc.model.AuthTokenInfo;
import com.websystique.springmvc.model.User;
 
public class SpringRestClient {
 
    public static final String REST_SERVICE_URI = "http://localhost:8080/SpringSecurityOAuth2Example";
    
    public static final String AUTH_SERVER_URI = "http://localhost:8080/SpringSecurityOAuth2Example/oauth/token";
    
    public static final String QPM_PASSWORD_GRANT = "?grant_type=password&username=bill&password=abc123";
    
    public static final String QPM_ACCESS_TOKEN = "?access_token=";

    /*
     * Prepare HTTP Headers.
     */
    private static HttpHeaders getHeaders(){
    	HttpHeaders headers = new HttpHeaders();
    	headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
    	return headers;
    }
    
    /*
     * Add HTTP Authorization header, using Basic-Authentication to send client-credentials.
     */
    private static HttpHeaders getHeadersWithClientCredentials(){
    	String plainClientCredentials="my-trusted-client:secret";
    	String base64ClientCredentials = new String(Base64.encodeBase64(plainClientCredentials.getBytes()));
    	
    	HttpHeaders headers = getHeaders();
    	headers.add("Authorization", "Basic " + base64ClientCredentials);
    	return headers;
    }    
    
    /*
     * Send a POST request [on /oauth/token] to get an access-token, which will then be send with each request.
     */
    @SuppressWarnings({ "unchecked"})
	private static AuthTokenInfo sendTokenRequest(){
        RestTemplate restTemplate = new RestTemplate(); 
        
        HttpEntity<String> request = new HttpEntity<String>(getHeadersWithClientCredentials());
        ResponseEntity<Object> response = restTemplate.exchange(AUTH_SERVER_URI+QPM_PASSWORD_GRANT, HttpMethod.POST, request, Object.class);
        LinkedHashMap<String, Object> map = (LinkedHashMap<String, Object>)response.getBody();
        AuthTokenInfo tokenInfo = null;
        
        if(map!=null){
        	tokenInfo = new AuthTokenInfo();
        	tokenInfo.setAccess_token((String)map.get("access_token"));
        	tokenInfo.setToken_type((String)map.get("token_type"));
        	tokenInfo.setRefresh_token((String)map.get("refresh_token"));
        	tokenInfo.setExpires_in((int)map.get("expires_in"));
        	tokenInfo.setScope((String)map.get("scope"));
        	System.out.println(tokenInfo);
        	//System.out.println("access_token ="+map.get("access_token")+", token_type="+map.get("token_type")+", refresh_token="+map.get("refresh_token")
        	//+", expires_in="+map.get("expires_in")+", scope="+map.get("scope"));;
        }else{
            System.out.println("No user exist----------");
            
        }
        return tokenInfo;
    }
    
    /*
     * Send a GET request to get list of all users.
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    private static void listAllUsers(AuthTokenInfo tokenInfo){
    	Assert.notNull(tokenInfo, "Authenticate first please......");

    	System.out.println("\nTesting listAllUsers API-----------");
        RestTemplate restTemplate = new RestTemplate(); 
        
        HttpEntity<String> request = new HttpEntity<String>(getHeaders());
        ResponseEntity<List> response = restTemplate.exchange(REST_SERVICE_URI+"/user/"+QPM_ACCESS_TOKEN+tokenInfo.getAccess_token(),
        		HttpMethod.GET, request, List.class);
        List<LinkedHashMap<String, Object>> usersMap = (List<LinkedHashMap<String, Object>>)response.getBody();
        
        if(usersMap!=null){
            for(LinkedHashMap<String, Object> map : usersMap){
                System.out.println("User : id="+map.get("id")+", Name="+map.get("name")+", Age="+map.get("age")+", Salary="+map.get("salary"));;
            }
        }else{
            System.out.println("No user exist----------");
        }
    }
     
    /*
     * Send a GET request to get a specific user.
     */
    private static void getUser(AuthTokenInfo tokenInfo){
    	Assert.notNull(tokenInfo, "Authenticate first please......");
        System.out.println("\nTesting getUser API----------");
        RestTemplate restTemplate = new RestTemplate();
        HttpEntity<String> request = new HttpEntity<String>(getHeaders());
        ResponseEntity<User> response = restTemplate.exchange(REST_SERVICE_URI+"/user/1"+QPM_ACCESS_TOKEN+tokenInfo.getAccess_token(),
        		HttpMethod.GET, request, User.class);
        User user = response.getBody();
        System.out.println(user);
    }
     
    /*
     * Send a POST request to create a new user.
     */
    private static void createUser(AuthTokenInfo tokenInfo) {
    	Assert.notNull(tokenInfo, "Authenticate first please......");
        System.out.println("\nTesting create User API----------");
        RestTemplate restTemplate = new RestTemplate();
        User user = new User(0,"Sarah",51,134);
        HttpEntity<Object> request = new HttpEntity<Object>(user, getHeaders());
        URI uri = restTemplate.postForLocation(REST_SERVICE_URI+"/user/"+QPM_ACCESS_TOKEN+tokenInfo.getAccess_token(),
        		request, User.class);
        System.out.println("Location : "+uri.toASCIIString());
    }
 
    /*
     * Send a PUT request to update an existing user.
     */
    private static void updateUser(AuthTokenInfo tokenInfo) {
    	Assert.notNull(tokenInfo, "Authenticate first please......");
        System.out.println("\nTesting update User API----------");
        RestTemplate restTemplate = new RestTemplate();
        User user  = new User(1,"Tomy",33, 70000);
        HttpEntity<Object> request = new HttpEntity<Object>(user, getHeaders());
        ResponseEntity<User> response = restTemplate.exchange(REST_SERVICE_URI+"/user/1"+QPM_ACCESS_TOKEN+tokenInfo.getAccess_token(),
        		HttpMethod.PUT, request, User.class);
        System.out.println(response.getBody());
    }
 
    /*
     * Send a DELETE request to delete a specific user.
     */
    private static void deleteUser(AuthTokenInfo tokenInfo) {
    	Assert.notNull(tokenInfo, "Authenticate first please......");
        System.out.println("\nTesting delete User API----------");
        RestTemplate restTemplate = new RestTemplate();
        HttpEntity<String> request = new HttpEntity<String>(getHeaders());
        restTemplate.exchange(REST_SERVICE_URI+"/user/3"+QPM_ACCESS_TOKEN+tokenInfo.getAccess_token(),
        		HttpMethod.DELETE, request, User.class);
    }
 
 
    /*
     * Send a DELETE request to delete all users.
     */
    private static void deleteAllUsers(AuthTokenInfo tokenInfo) {
    	Assert.notNull(tokenInfo, "Authenticate first please......");
        System.out.println("\nTesting all delete Users API----------");
        RestTemplate restTemplate = new RestTemplate();
        HttpEntity<String> request = new HttpEntity<String>(getHeaders());
        restTemplate.exchange(REST_SERVICE_URI+"/user/"+QPM_ACCESS_TOKEN+tokenInfo.getAccess_token(),
        		HttpMethod.DELETE, request, User.class);
    }
 
    public static void main(String args[]){
    	AuthTokenInfo tokenInfo = sendTokenRequest();
    	listAllUsers(tokenInfo);
        
    	getUser(tokenInfo);
        
    	createUser(tokenInfo);
        listAllUsers(tokenInfo);
        
        updateUser(tokenInfo);
        listAllUsers(tokenInfo);
        
        deleteUser(tokenInfo);
        listAllUsers(tokenInfo);
        
        deleteAllUsers(tokenInfo);
        listAllUsers(tokenInfo);
    }
}

Above code will produce following output:

AuthTokenInfo [access_token=fceed386-5923-4bf8-b193-1d76f95da4c4, token_type=bearer, refresh_token=29d28ee2-9d09-483f-a2d6-7f93e7a31667, expires_in=71, scope=read write trust]

Testing listAllUsers API-----------
User : id=1, Name=Sam, Age=30, Salary=70000.0
User : id=2, Name=Tom, Age=40, Salary=50000.0
User : id=3, Name=Jerome, Age=45, Salary=30000.0
User : id=4, Name=Silvia, Age=50, Salary=40000.0

Testing getUser API----------
User [id=1, name=Sam, age=30, salary=70000.0]

Testing create User API----------
Location : http://localhost:8080/SpringSecurityOAuth2Example/user/5

Testing listAllUsers API-----------
User : id=1, Name=Sam, Age=30, Salary=70000.0
User : id=2, Name=Tom, Age=40, Salary=50000.0
User : id=3, Name=Jerome, Age=45, Salary=30000.0
User : id=4, Name=Silvia, Age=50, Salary=40000.0
User : id=5, Name=Sarah, Age=51, Salary=134.0

Testing update User API----------
User [id=1, name=Tomy, age=33, salary=70000.0]

Testing listAllUsers API-----------
User : id=1, Name=Tomy, Age=33, Salary=70000.0
User : id=2, Name=Tom, Age=40, Salary=50000.0
User : id=3, Name=Jerome, Age=45, Salary=30000.0
User : id=4, Name=Silvia, Age=50, Salary=40000.0
User : id=5, Name=Sarah, Age=51, Salary=134.0

Testing delete User API----------

Testing listAllUsers API-----------
User : id=1, Name=Tomy, Age=33, Salary=70000.0
User : id=2, Name=Tom, Age=40, Salary=50000.0
User : id=4, Name=Silvia, Age=50, Salary=40000.0
User : id=5, Name=Sarah, Age=51, Salary=134.0

Testing all delete Users API----------

Testing listAllUsers API-----------
No user exist----------

Project Structure

SpringOAuth2_img10

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.websystique.springmvc</groupId>
	<artifactId>SpringSecurityOAuth2Example</artifactId>
	<version>1.0.0</version>
	<packaging>war</packaging>

	<name>SpringSecurityOAuth2Example</name>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<springframework.version>4.3.1.RELEASE</springframework.version>
		<springsecurity.version>4.1.1.RELEASE</springsecurity.version>
		<springsecurityoauth2.version>2.0.10.RELEASE</springsecurityoauth2.version>
		<jackson.library>2.7.5</jackson.library>
	</properties>

	<dependencies>
		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${springframework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${springframework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${springframework.version}</version>
		</dependency>

		<!-- Spring Security -->
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-web</artifactId>
			<version>${springsecurity.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-config</artifactId>
			<version>${springsecurity.version}</version>
		</dependency>

		<!-- Spring Security OAuth2-->
		<dependency>
		    <groupId>org.springframework.security.oauth</groupId>
		    <artifactId>spring-security-oauth2</artifactId>
		    <version>${springsecurityoauth2.version}</version>
		</dependency>

		<!-- Jackson libraries -->
		<dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.library}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
            <version>${jackson.library}</version>
        </dependency>

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
		</dependency>
	</dependencies>

	<build>
			<plugins>
				<plugin>
                	<groupId>org.apache.maven.plugins</groupId>
                	<artifactId>maven-compiler-plugin</artifactId>
                	<version>3.2</version>
                	<configuration>
                    	<source>1.7</source>
                    	<target>1.7</target>
                	</configuration>
            	</plugin>			
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-war-plugin</artifactId>
					<version>2.4</version>
					<configuration>
						<warSourceDirectory>src/main/webapp</warSourceDirectory>
						<warName>SpringSecurityOAuth2Example</warName>
						<failOnMissingWebXml>false</failOnMissingWebXml>
					</configuration>
				</plugin>
			</plugins>
		<finalName>SpringSecurityOAuth2Example</finalName>
	</build>
</project>

Download Source Code



References

If you like tutorials on this site, why not take a step further and connect me on Facebook , Google Plus & Twitter as well? I would love to hear your thoughts on these articles, it will help me improve further our learning process.

If you appreciate the effort I have put in this learning site, help me improve the visibility of this site towards global audience by sharing and linking this site from within and beyond your network. You & your friends can always link my site from your site on www.websystique.com, and share the learning.

After all, we are here to learn together, aren’t we?

  • Pingback: تعمیر یخچال در محل()

  • Pingback: strap on dildo()

  • Pingback: bondage play()

  • Pingback: ترمیم مو، کاشت مو ، مو طبیعی()

  • Pingback: ترمیم مو و کاشت مو()

  • Pingback: فروش دوربین های مدار بسته مخفی()

  • Pingback: نصب دوربین های مدار بسته()

  • Pingback: sex swing()

  • Pingback: طراحی وب سایت()

  • Pingback: Type Beats()

  • Pingback: Lil Wayne()

  • Pingback: فروش دوربین های مدار بسته مخفی()

  • Pingback: نصب و اجرای دوربین مداربسته()

  • Pingback: ترمیم مو و کاشت مو()

  • Pingback: http://www.mcvj.com/profile/ringgaard30rosenthal()

  • Pingback: sex toy reviews()

  • Pingback: magic wand()

  • Pingback: Black V-neck martial arts uniform()

  • Pingback: طراحی سایت وکیل()

  • Pingback: edible body paint()

  • Pingback: نصب دوربین های مدار بسته()

  • Pingback: double sided dildo()

  • Pingback: Floor protection()

  • Pingback: Magnets()

  • Pingback: خريد اپل ايدي()

  • Pingback: lgbt sex toys()

  • Pingback: کفسابی در تهران()

  • Pingback: وکیل()

  • Pingback: Adamandeve.com()

  • Pingback: strap-on dildo()

  • Pingback: american whopper()

  • Pingback: Помощь психолога()

  • Pingback: magic wand massager()

  • Pingback: best sex games()

  • Pingback: buy kvass()

  • Pingback: adam and eve tv shopping()

  • Pingback: 14 oz ultra heavyweight white karate uniform()

  • Pingback: driving tips()

  • Pingback: bangal ka jadu()

  • Pingback: Mikemaid_7447()

  • Pingback: bangal ka jadu()

  • Pingback: Cock ring()

  • Pingback: Nipple Toys()

  • Pingback: محصولات دوربین مدار بسته()

  • Pingback: Anal toys()

  • Pingback: men massaging men()

  • Pingback: glass sex toy()

  • Pingback: triple vibrator()

  • Pingback: Dildo()

  • Pingback: Butt plugs()

  • Pingback: bookkeeping()

  • Pingback: rabbit vibrators()

  • Pingback: thegayfrat()

  • Pingback: راهنمای خرید دوربین مداربسته()

  • Pingback: rabbit sex toy()

  • Pingback: Tang soo do uniform gi()

  • Pingback: digital download script()

  • Pingback: how cholesterol levels predict your health()

  • Pingback: home()

  • Pingback: etoro()

  • Pingback: auction marketplace()

  • Pingback: non-conforming()

  • Pingback: Download Free Mr Crack Mixtapes()

  • Pingback: Download Blends Mixtapes Free()

  • Pingback: Download Free Future Mixtapes()

  • Pingback: Tam Coc Ninh Binh()

  • Pingback: ノロウイルス()

  • Pingback: ocean rates()

  • Pingback: Album Leaks()

  • Pingback: revize zdvihacich zarizeni()

  • Pingback: Jadakiss()

  • Pingback: play online games on pc()

  • Pingback: actual-news.pro()

  • Pingback: Proforce 7 oz poly/cotton black uniform()

  • Pingback: http://tarmimemoo.net()

  • Pingback: urgent care glendale()

  • Pingback: best couples toys()

  • Pingback: ترمیم موی بانوان()

  • Pingback: sex cream to last longer walmart()

  • Pingback: Clone-a-willy()

  • Pingback: egg vibrator()

  • Pingback: couple in bed()

  • Pingback: rechargeable bullet vibrator()

  • Pingback: clitoral stimulator()

  • Pingback: bullet sex toy()

  • Pingback: دوچرخه ثابت()

  • Pingback: خرید اپل ایدی ارزون()

  • Pingback: اجاره ويلا استخردار در كردان()

  • Pingback: prostate massager()

  • Pingback: vibrator()

  • Pingback: adam and eve()

  • Pingback: pure skin dildo()

  • Pingback: kala jadu()

  • Pingback: خرید اپل ایدی ارزان()

  • Pingback: magnets()

  • Pingback: خرید آنلاین تردمیل خانگی()

  • Pingback: black polythene()

  • Pingback: polythene()

  • Pingback: adam \u0026 eve magic massager()

  • Pingback: doc johnson()

  • Pingback: signs your partner is cheating()

  • Pingback: escort()

  • Pingback: NasstoysNewYork()

  • Pingback: sex restraint()

  • Pingback: erotic()

  • Pingback: خرید اپل ایدی()

  • Pingback: PHP Programmer()

  • Pingback: gays sex toys()

  • Pingback: Oral()

  • Pingback: female vibrators()

  • Pingback: A\u0026E Love Bullet()

  • Pingback: Bob Mannequin Bag with groin()

  • Pingback: vpn خرید برای گوشی()

  • Pingback: traditional anime()

  • Pingback: adamandeve.com()

  • Pingback: life like dong()

  • Pingback: roleplay sex()

  • Pingback: ترمیم مو()

  • Pingback: My Homepage()

  • Pingback: payday loan()

  • Pingback: dual action vibrator()

  • Pingback: internação compulsória()

  • Pingback: robert()

  • Pingback: adam and eve sex toy()

  • Pingback: Crystal Jellies Anal Starter()

  • Pingback: waterproof bullet vibrator()

  • Pingback: TPM()

  • Pingback: stock trading basics()

  • Pingback: adam and eve penis pump()

  • Pingback: Using Ben Wa Balls()

  • Pingback: Sex Toy for Men()

  • Pingback: How To Stimulate G Spot()

  • Pingback: male masturbator review()

  • Pingback: flexible dildo()

  • Pingback: icicles()

  • Pingback: wand vibrator()

  • Pingback: Adam \u0026 Eve()

  • Pingback: my first vibrator()

  • Pingback: смотреть онлайн фильмы 2017()

  • Pingback: apps for windows pc download()

  • Pingback: Inland Empire Ca()

  • Pingback: pc games for windows 10()

  • Pingback: free pc games download()

  • Pingback: free download for windows 7()

  • Pingback: xxx hd video()

  • Pingback: lingerie babydoll()

  • Pingback: rubber duck vibrator()

  • Pingback: dildo()

  • Pingback: Adam and Eve()

  • Pingback: sex doctor()

  • Pingback: Top Gauge Professional Pump()

  • Pingback: sunny leone xxx()

  • Pingback: Anal Beads()

  • Pingback: turkey men's printing suit Factory()

  • Pingback: Vibrating Penis Ring()

  • Pingback: adam \u0026 eve()

  • Pingback: best g-spot vibrator()

  • Pingback: USB Vibrator()

  • Pingback: Male Masturbator Review()

  • Pingback: tubepatrol.net()

  • Pingback: jbeatz()

  • Pingback: best g spot vibrator()

  • Pingback: paydaycgtloansnhj.com()

  • Pingback: clit vibrator()

  • Pingback: Magic Rabbit Wand Attachment()

  • Pingback: female sex toys()

  • Pingback: gay anal sex toys()

  • Pingback: pleasure ring()

  • Pingback: whopper sex toys()

  • Pingback: A/C Compressor()

  • Pingback: نصب دوربین مداربسته()

  • Pingback: adam and eve sex toys()

  • Pingback: luxury sex toys()

  • Pingback: before having sex()

  • Pingback: ed pumps for sale()

  • Pingback: best vibrator()

  • Pingback: adult sex toy()

  • Julio Gabriel Vera

    Thanks for Oauth2 tutorial, I’ve tried to applied to http://websystique.com/springmvc/spring-mvc-4-and-spring-security-4-integration-example/ but I get this exception: Error creating bean with name ‘appConfig’: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration’: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘metaDataSourceAdvisor’: Cannot resolve reference to bean ‘methodSecurityMetadataSource’ while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘methodSecurityConfig’: Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method ….. nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name ‘getAuthenticationTrustResolver’: Requested bean is currently in creation: Is there an unresolvable circular reference? Could you show us the previus example with Oauth2 ? Thanks

  • Pingback: ecu chip tuning()

  • Pingback: PVC Touch Paper()

  • Pingback: vanity desk with lighted mirror()

  • Pingback: hair loss clinic Singapore()

  • Pingback: download free games for windows()

  • Pingback: flex vibrator’s bendabl()

  • Pingback: How to be a Better Lover()

  • Pingback: sex kit()

  • Pingback: adamandeve.com()

  • Pingback: adult sex shop()

  • Pingback: petroleum()

  • Pingback: Martial Arts Karate Taekwondo Uniforms()

  • Pingback: vibrating anal plug()

  • Pingback: adam and eve()

  • Ashutosh Kapil

    hi @websystique:disqus, I am not able to find the code where the access token is being generated and is validated on the time of accessing the user information.

  • Pingback: adam and eve()

  • Pingback: ac repair()

  • Pingback: app for pc()

  • Pingback: free download for pc()

  • Pingback: pc games for windows 7()

  • Pingback: first anal toy()

  • Pingback: rabbit vibrator()

  • Pingback: free download for windows pc()

  • Pingback: adam and eve sex toys()

  • Pingback: http://mer99furniture.com()

  • Pingback: apps for pc download()

  • Pingback: costume lingerie()

  • Pingback: gay sex()

  • Pingback: spice things up in the bed()

  • Pingback: backhoe repairs()

  • Pingback: divorce in PA()

  • Pingback: web site()

  • Pingback: sex straps()

  • Pingback: pc games for windows xp()

  • Pingback: lasting longer in bed()

  • Pingback: Sripatum university()

  • Pingback: Carpet steam cleaning Melbourne()

  • Pingback: water based lube()

  • Pingback: male toys()

  • Pingback: good head kit()

  • Pingback: Under The Bed Restraint System()

  • Pingback: Personal Lubricant()

  • Pingback: Super Head Honcho Review()

  • Pingback: Blue Dolphin Vibrator()

  • Pingback: Arousal Cream()

  • Pingback: Personal Massager()

  • Pingback: Magic Massager Deluxe()

  • Pingback: Butterfly Sex Toy()

  • Pingback: luxe vibe()

  • Pingback: realistic vibrator()

  • Pingback: wild rabbit vibrator()

  • Mahesh Narkar

    First of all its really helpful and nice example. But its giving me following error.

    HTTP Status 404 – /SpringSecurityOAuth2Example/oauth/token

    then i tried with http://localhost:8080/SpringSecurityOAuth2Example/user/ just make sure there is no problem in request handling. But still it gives me 404 error.

  • Pingback: interior design Singapore()

  • Pingback: kala jadu()

  • Pingback: Top Sports Stories and Sports Headlines()

  • Pingback: bandiere()

  • Pingback: home cleaning Melbourne()

  • Pingback: vibrating dildo with scution cup()

  • Pingback: Ring Candles()

  • Pingback: butt plug()

  • Pingback: butt plug()

  • Pingback: butt plug()

  • Pingback: gay toys()

  • Pingback: butt plug()

  • Pingback: terminix bed bugs()

  • Pingback: house cleaning Melbourne()

  • Pingback: Healthy food easy to prepare()

  • Pingback: tips to make your wife happy()

  • Pingback: adam and eve sex toys()

  • Sachin Rai

    Hi ,
    I am getting following error on running project in eclipse:
    HTTP Status [404] – [Not Found]

  • Pingback: brush cutter handle switch()

  • Pingback: vinyl()

  • Pingback: end of tenancy cleaning Melbourne()

  • Pingback: sex toys for couples()

  • Pingback: realistic dildo()

  • Pingback: apps for pc download()

  • Pingback: click here()

  • Pingback: womens vibrator()

  • Pingback: Hot Hot Hot Site()

  • Pingback: Daily and Instant News Update()

  • Pingback: butt plug()

  • Pingback: lifelike dildo()

  • Pingback: circles()

  • Pingback: bangal ka jadu()

  • Pingback: first time vibrator()

  • Pingback: most powerful vibrator()

  • Pingback: Venture Point Network()

  • Pingback: web design company()

  • Pingback: rampant rabbit vibrator()

  • Pingback: silicone containers()

  • Pingback: Queen duvet cover()

  • Pingback: online scr game()

  • Pingback: nipple erector()

  • Pingback: free download for windows 7()

  • Pingback: triple vibrator()

  • Pingback: realistic vibrator()

  • Pingback: female vibrator()

  • Pingback: adam and eve sex toys()

  • Pingback: realistic vibrating dildo()

  • Pingback: honey usa()

  • Pingback: Jewelry()

  • Pingback: download music video()

  • Pingback: tratamento Alcoolismo()

  • Pingback: coffee’s best kona()

  • Pingback: coffee’s best kona()

  • Pingback: RMUTT Thailand()

  • Pingback: coffee, 100% kona()

  • Pingback: adam and eve()

  • Pingback: ean codes()

  • Pingback: 假面DVD()

  • Pingback: newport beach surfboard rental()

  • Pingback: luxury bullet sex toy()

  • Pingback: rampant rabbit sex toys()

  • Pingback: sex toy review()

  • Pingback: adam eve toys()

  • Pingback: best sex toy cleaner()

  • Pingback: hands free sex toys()

  • Abhinav Vivekanand

    After importing this project into STS, getting issues. How do I run this project in STS

  • Melissa Palmer

    Hi, where or how are you actually restricting functions/methods of your Rest API to the different ROLES? For example how do you restrict that only users with ADMIN role can use all of createUser, updateUser, deleteUser, listAllUsers, getUser
    where as users with only USER role can only use functions listAllUsers, getUser

    Thanks in Advance

  • Pingback: lucid dream vibrator()

  • Pingback: vintage collectibles()

  • Pingback: snuff bottles()

  • Pingback: nebbia()

  • Pingback: Evil eye()

  • Pingback: Lefkoşa satılık villa()

  • Pingback: wall bed mechanism()

  • Pingback: Make Money Online()

  • Pingback: web site()

  • Pingback: barcode kaufen()

  • Pingback: usa email lists()

  • Pingback: Birthday Needs The Use Of Java Code – Master LM()

  • Pingback: Dongfeng()

  • Pingback: Pain Relief Oil()

  • oleg

    Good day. I received an error
    {
    “error”: “invalid_client”,
    “error_description”: “Bad client credentials”
    }

    What can you recommend?

  • Pingback: clinica de recuperação()

  • Pingback: Double Dildo Video()

  • Pingback: global online franchise scam()

  • Pingback: dildo()

  • Pelly S

    Hi @websystique:disqus You mentioned “We will be using resource owner password credentials grant type. The reason is simple, we are not implementing a view which redirects us to a login page. ”
    My question is, is it ok to use resource owner password credentials grant type when implementing a view, instead of just using Postman or RestTemplate. Do you have an idea on how to handle the authentication (login/logout) with view / UI server? Thank you in advance.

  • Pingback: every day deals portland()

  • Pingback: kona 100%()

  • Pingback: best kona()

  • John

    Hi @websystique:disqus
    I have an Autowire problem with where the MethodSecurityConfig’s AutoWire private OAuth2SecurityConfiguration securityConfig; crashes my springboot application.

  • Pingback: work from home and make money()

  • Pingback: cock ring()

  • Pingback: cheap retro jordans()

  • Pingback: women()

  • Pingback: rehab clinic()

  • Pingback: men clothing()

  • Pingback: Web Application Development Company()

  • Pingback: ventura yellowpage()

  • Ashika Umanga Umagiliya

    hi @websystique:disqus , thanks alot for the tutorial.
    I want to integrate my Spring RestAPI with external AuthorizationServer (ADFS). I assume for this my Spring RestAPI need to communicate with the AuthorizationServer using RestAPI (or WS). How to realize this case ?

  • Pingback: lovehoney()

  • Pingback: Buy Empty capsules- Vcaps()

  • Pingback: Army regulation issue boots()

  • Suwardi Lazzuardi

    Nice article…
    I’m try and connect to db using jdbc running successfuly.
    I want to ask, how to move /user/?access_token=*********** from url to header? Any idea for this?
    Thanks before…

  • Antonio Teixeira

    Hi
    @websystique:disqus ,

    i can get access_token in API http://localhost:8080/SpringSecurityOAuth2Example/oauth/token?grant_type=password&username=bill&password=abc123 .

    however when i call api :http://localhost:8080/SpringSecurityOAuth2Example/user/?access_token=6b5c24cb-f9d7-48d0-8745-543be35f70c5 . i take error :
    {
    “error”: “invalid_token”,
    “error_description”: “Invalid access token: 6b5c24cb-f9d7-48d0-8745-543be35f70c5″
    }

    And i already have increase the time to expire the token. Any idea why? or what options i have to put in get screen?

    Thanks in advanced

    • John

      The tokenstore might be the problem. Create a static tokenstore and use that one in all the classes. This might solve the problem.

      • Sagar Kapadia

        Hi John, can you explain this in a bit more detail, please? I am facing the same problem.

        • John

          Hi. You want to implement the UserDetails interface and make a custom class of that. You can use that across your application. Make a method:

          @Bean
          public CustomUserDetailsService customUserDetailsService(){return new CustomerUserDetailsService()}

          Now you can use the @Autowire because there is a @Bean of that class. Now you can make a custom implementation of the tokenstore. Implement the interface (or extend the baseclass, i forgot which one you’re supposed to do) and then make that class a Singleton! Now that it’s a static class and a singleton you’re sure that wherever you use the class it’s
          The correct instance and your tokens will be the same! The token store uses the userdetailsservice that you created early on. So make a private variable of that in the tokenstore singleton class. Like this: @Autowire private CustomUserDetails customUserDetails; hope it helps!

  • Pingback: Buy Craft Beer Online()

  • Pingback: Happy 1st Birthday()

  • Pingback: Birthday wishes for lover()

  • Pingback: Strap On Dildo()

  • Pingback: outcall()

  • Pingback: tooth extraction()

  • Pingback: fishing redding()

  • Pingback: TensorFlow()

  • Pingback: pure kona()

  • Pingback: pure kona()

  • Pingback: dance instructor()

  • Pingback: Glass Sex Toys()

  • Pingback: Top Ten Sex Toys()

  • Pingback: Bondage()

  • Pingback: sexually transmitted diseases()

  • Pingback: http://www.hamptonbaylightinghd.com()

  • Pingback: http://www.motupatlugameshd.com()

  • kuramama

    Good ideas ! Speaking of which if others are interested in a FL Itemized Invoice Affidavit , my family came across a template document here https://goo.gl/SgD2Xm

  • Michael

    Hi, i ma new to spring. when i run downloaded project with “mvn spring:boot:run” i get error “No plugin found for prefix ‘spring-boot’ in the current project”.
    could you help me out with this issue?

    • websystique

      Hi Michael, this is not a spring-boot project.

      • Michael

        thanks for reply.
        could you let me know how can i start project from command line?
        it is running in Eclipse but i would like to run from window CMD. thanks

  • Pingback: movies()

  • Pingback: nSpire Network Signup()

  • Pingback: robert()

  • Pingback: Sprinkler system()

  • Pingback: Tablet repair()

  • Pingback: buy kona()

  • Pingback: pure kona()

  • Pingback: real estate daytona()

  • Pingback: http://motuandpatlugames.com()

  • Pingback: sex stories()

  • Pingback: motu and patlu games()

  • Pingback: LED light sources Sanlibang()

  • Pingback: Los Angeles()

  • Pingback: 100% kona()

  • Pingback: sell()

  • Pingback: Google()

  • Sergey Morenets

    Hi websystique

    I downloaded your sources and run application using Jetty 9.4 with context path ‘/’. However when I try to issue POST request in POSTMAN: http://localhost:8080/oauth/token?grant_type=password&username=bill&password=abc123

    I get error message: Problem accessing /oauth/token. Reason:Full authentication is required to access this resource
    Can you please help?

  • Martijn Hiemstra

    Unfortunately this tutorial doesn’t work. I get a bad credentials message. I have tried curl and using the browser. I am using Spring boot 1.5.2.

  • Dhyanandra Singh

    Hello @websystique:disqus ,
    i am trying to implement oauth2 with spring boot application and getting error :

    @Bean method OAuth2ResourceServerConfig.tokenServices called as a bean reference for type [org.springframework.security.oauth2.provider.token.DefaultTokenServices] but overridden by non-compatible bean instance of type [com.sun.proxy.$Proxy108]

    i searched but not getting anything so can you help me with this what i did wrong.
    thanks .

  • Kanwaljit Singh

    This project works like a charm…. -:)
    I have two other thongs that I wanna ask. Firstly, What if I have to use an external Oauth provides for this. Can you point me to an example for that or usage ?
    Secondly, what would I need to do to run this in Springboot instead ?

  • Hân Siro

    Hi
    @websystique:disqus I want access with DB . example we will have a access_token and a user on time in code java how to i can get access_token expired time… to store in DB ?

  • Raminator

    Hello websystique, the password grant works as expected, so thank you for that. Do you have an example for Implicit? I would very much like and appreciate that . Thank you.

  • Pingback: Hibernate One-To-One Bidirectional with Shared Primary Key (Annotation) - WebSystique()

  • Chirag Kevadiya

    HI @websystique:disqus

    Thanks for the articals …

    when i use tow HttpSecurity one for webpanel and one for rest api (oauth2). but it not working.

    @EnableWebSecurity
    public class SpringSecurity {

    @Autowired
    public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication().withUser(“admin”).password(“admin”).roles(“ADMIN”);
    }

    @Configuration
    @Order(1)
    public static class WebSiteSecurity extends WebSecurityConfigurerAdapter{

    /*@Autowired
    private DataSource dataSource;

    @Autowired
    public void configAuthentication(AuthenticationManagerBuilder authentication) throws Exception {
    authentication.jdbcAuthentication().dataSource(dataSource)
    .usersByUsernameQuery(“select u.user_name, u.password, u.status from users u where u.user_name = ?”)
    .authoritiesByUsernameQuery(
    “select u.user_name, ur.role from user_role ur, users u where ur.user_name =?”);
    }*/

    @Override
    public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers(“/assets/**”, “/upload/**”);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable().authorizeRequests().antMatchers(“/login”).permitAll().antMatchers(“/*”)
    .access(“hasRole(‘ADMIN’)”).anyRequest().authenticated().and().formLogin().loginPage(“/login”)
    .usernameParameter(“ssoId”).passwordParameter(“password”).defaultSuccessUrl(“/index”)
    .failureUrl(“/login?error”).and().logout().logoutSuccessUrl(“/login?logout”)
    .deleteCookies(“JSESSIONID”).invalidateHttpSession(true).and().csrf().and().sessionManagement()
    .invalidSessionUrl(“/login?logout”).maximumSessions(1);
    }
    }

    @Configuration
    public static class RestSecurity extends WebSecurityConfigurerAdapter{

    @Autowired
    private ClientDetailsService clientDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable().anonymous().disable().authorizeRequests().antMatchers(“/oauth/token”).permitAll();
    }

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

    @Bean
    public TokenStore tokenStore() {
    return new InMemoryTokenStore();
    }

    @Bean
    @Autowired
    public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore) {
    TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
    handler.setTokenStore(tokenStore);
    handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
    handler.setClientDetailsService(clientDetailsService);
    return handler;
    }

    @Bean
    @Autowired
    public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
    TokenApprovalStore store = new TokenApprovalStore();
    store.setTokenStore(tokenStore);
    return store;
    }
    }
    }

  • Hân Siro

    Hi
    @websystique:disqus ,

    could you share file web.xml, cuz i can get access_token in API http://localhost:8080/myproject/oauth/token?grant_type=password&username=bill&password=abc123 .

    however when i call api :http://localhost:8080/myproject/user/?access_token=6b5c24cb-f9d7-48d0-8745-543be35f70c5 . i take error :
    {
    “error”: “invalid_token”,
    “error_description”: “Invalid access token: 6b5c24cb-f9d7-48d0-8745-543be35f70c5″
    }

    • websystique

      Hello Siro, this is pure Javaconfig setup, no web.xml. On ypur issue, I think your access token is not valid anymore and you should refresh it using refresh token.

      • Hân Siro

        I solved use Javaconfig and web.xml. Thanks for guideline

        • kiran

          Hi,

          I would like to configure spring mvc with this setup. How can i configure web.xml and appservlet.xml under WEB-INF.

          Thanks

      • Hân Siro

        Hi @websystique:disqus can i custom grant_type=password&username=ferrari&password=spring in requesstBody? cuz i see username and password in url is no security?

  • Ibrahim Erol

    Hi @websystique:disqus
    I will be glad if you could take a look at this. I used this api as a skeleton and built my own app. Im using jdbc and so on. But anyways, with the Angular2 client i get pre-flight issue all the time. Millions of things i have tried but still no help. I have the pre-flights authorized as well as following but still doesnt work

    http.authorizeRequests().antMatchers(“HttpMethod.OPTIONS”, “/**”).permitAll();
    Btw, In the logs from catalina.out from server, i observe that for some reason user is logged in as anonymous

    • Maciej G

      Hi, my previous post was detected as spam. Don’t know why… Again without URLs:
      Annotation @EnableAuthorizationServer imports AuthorizationServerSecurityConfiguration class which adds fully authentication to “/oauth/token” endpoint with order 0. To allow anonymous access for OPTIONS method (e.g. Angular2 pre-flight requests) you might extend Spring implementation of @EnableAuthorizationServer and AuthorizationServerSecurityConfiguration and add permissions for required OAuth endpoints. Then you have to replace annotation @EnableAuthorizationServer in your AuthorizationServeConfigurerAdapter implementation.

  • Chris P.

    Hey @websystique:disqus, I’ve been trying to find a solution to this for day and it may very well be impossible, however any insight would be appreciated.
    What I would like to accomplish is almost exactly like what you have here, except I don’t want to need a token to create a new user. The easiest solution is to just disable all filters on the end point like:

    web.ignoring().antMatchers(“/user/create”);

    The catch though is that on this one endpoint, i still want to require the client and client secret as Basic Auth.
    So, for example, creating a new user would include sending a PUT request with the new user info, along with Basic Authentication of the client and client secret, but no need for an access token.

    Is this possible at all? Any ideas?

    Cheers,
    Chris

    • websystique

      Hello Chris, I think conceptually it is possible. I wonder if you create a seperate endpoint [with seperate security configuration] to handle that specific [create] use case, and for rest you use this typical token based setup. I did not try programmatically, but i think it should be possible.

  • DemeCarv

    I am getting “[AUDIT ] CWWKS1100A: Authentication did not succeed for user ID my-trusted-client. An invalid user ID or password was specified” for any access, either to get a token string or get users. I am using Websphere Liberty Profile because we only use WebSphere here. I tried debug but such audit warn always is printed before “HttpServletResponse response = (HttpServletResponse) res;” in CORSFilter.doFilter. The funy thing is that everything works as descreibed here. Any clue what to check? Since I am using it as a base for certain application I must be asked why ” Authentication did not succeed…An invalid user ID…” message in WebSphere logs althought it works.

    • websystique

      just a thought, could it be that your websphere has some default security rules which probably expect the encrypted stuff/credentials? I don’t have a websphere installation here but since this stuff works on basic tomcat, i can’t think of much.

  • Anton

    Hi @websystique:disqus, thanks for the article, it’s very helpful. I have one question.
    It seems that TokenStoreUserApprovalHandler is not needed in this example and DefaultUserApprovalHandler should be enough. UserApprovalHandler is only used in AuthorizationEndpoint(/oauth/authorize), which is not used in your example because there is no approval flow. Am I missing anything?

    Without TokenStoreUserApprovalHandler config can be simplified a little bit.

  • Ibrahim Erol

    Hello
    I managed to work this project using jdbc authentication and jdbc TokenStore. Apart from that, do you know how can i add USER_ROLE in the response together with access_token ?

  • Ibrahim Erol

    Hi, @websystique
    i have a question about TokenStore. I managed to use Jdbc authentication instead of hard-coded users but the problem now is that each time server is restarted or anything is changed in my source code, by nature the tokens are flushed. Could you give a hint what is the easiest way to store tokens in mysql db as well ?

  • Umar Hussain

    I ran the application using Intellij 14 and Apacher server 8
    there is no dispatherservlet added in the web.xml , also there is no web.xml

    I got an error

    14-Feb-2017 16:40:21.522 INFO [RMI TCP Connection(5)-127.0.0.1] org.springframework.web.servlet.DispatcherServlet.initServletBean FrameworkServlet ‘dispatcher’: initialization completed in 79 ms
    [2017-02-14 04:40:21,574] Artifact SpringSecurityOAuth2Example:war exploded: Artifact is deployed successfully
    [2017-02-14 04:40:21,574] Artifact SpringSecurityOAuth2Example:war exploded: Deploy took 8,819 milliseconds
    Filtering on…………………………………………………..
    14-Feb-2017 16:40:21.933 WARNING [http-nio-8080-exec-1] org.springframework.web.servlet.PageNotFound.noHandlerFound No mapping found for HTTP request with URI [/] in DispatcherServlet with name ‘dispatcher’
    Filtering on…………………………………………………..
    14-Feb-2017 16:40:21.999 WARNING [http-nio-8080-exec-3] org.springframework.web.servlet.PageNotFound.noHandlerFound No mapping found for HTTP request with URI [/] in DispatcherServlet with name ‘dispatcher’
    14-Feb-2017 16:40:22.765 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory E:ApacheSoftWareapache-tomcat-8.0.28webappsmanager
    14-Feb-2017 16:40:23.011 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory E:ApacheSoftWareapache-tomcat-8.0.28webappsmanager has finished in 175 ms
    Filtering on…………………………………………………..
    14-Feb-2017 16:40:24.266 WARNING [http-nio-8080-exec-4] org.springframework.web.servlet.PageNotFound.noHandlerFound No mapping found for HTTP request with URI [/] in DispatcherServlet with name ‘dispatcher’
    Filtering on…………………………………………………..
    14-Feb-2017 16:40:25.658 WARNING [http-nio-8080-exec-5] org.springframework.web.servlet.PageNotFound.noHandlerFound No mapping found for HTTP request with URI [/favicon.ico] in DispatcherServlet with name ‘dispatcher’
    Filtering on…………………………………………………..
    14-Feb-2017 16:40:25.805 WARNING [http-nio-8080-exec-6] org.springframework.web.servlet.PageNotFound.noHandlerFound No mapping found for HTTP request with URI [/favicon.ico] in DispatcherServlet with name ‘dispatcher’

    • Hân Siro

      clear project

    • websystique

      Hi Umar, there is no web.xml in this project, complete javaconfig based setup.

  • Karthik

    Hi Websytique,
    I’m very new to spring security and rest service. I load the given project in my eclipse workspace. But i dont know how to run and where to start. Kindly help to start the application and also how do i convert this project into spring MVC

    • Almiriad

      Hi starting to learn Spring MVC through this project is probably not the best way, you should have a look @websystique:disqus others Spring tuto, they are really helpful !

  • Vinay Yadav

    please explain what if i want resource server separated what to do ?

  • Jmp Jmp

    Awesome example, It’s working as expected, I was facing the difficulties while running your project in Jboss/ Jboss EAP. It gives me an error below.
    oauth/token – URI not found- 404
    when I check the code for get servlet mapping. You have added “/” but in boss It required to have “/*”.
    I request you to add method comment in your code, If you wiil deploy this code in jboss/eap, you should have “/*” . This can be very useful for the other developers as well. As it might not be aware about this thing.

    @Override
    protected String[] getServletMappings() {
    return new String[] { “/*” };
    }

  • Pram

    Hi,
    I really like your example. Very clear. But passing user credentials in URL, doesn’t seem very safe. Is there another alternative to this. I want to create 2 micro-services ServiceA and ServiceB where both are resource-servers and ServiceA is client that calls ServiceB.

  • nexuscharles

    Everytime I try to generate a new token, I get this;

    {
    “timestamp”: 1485950199491,
    “status”: 403,
    “error”: “Forbidden”,
    “message”: “Access Denied”,
    “path”: “/ebillservices/clients/info-request/oauth/token”
    }

    This is the method;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    http
    .csrf().disable()
    .anonymous().disable()
    .authorizeRequests()
    .antMatchers(“/clients/info-request/oauth/token”).permitAll();
    }

  • Ged

    Works great! what changes would have to be done to it to make it work with spring boot? i have ported this setup to spring boot and it seems that ResourceServer is ignored, any URLs specified are non effective, any advice? nonetheless thanks for the great post!

    • Balaji Gumpena

      I have the same problem, did it work for you ?

  • Nikhil Ronghe

    Hey, Thanks for the article.

    One question i have is, how to make ?grant_type=password&username=bill&password=abc123 as a post request, Or json request.

  • Kunjan Shah

    Hey, @websystique:disqus

    I copied the exact source but I got the error of bad credential.
    My headers and basic auth type is same.
    but still i facing the same.

    Kindly help me.

  • Ged

    Great post that actually works, quick question though, how do you log out?

    • websystique

      Hi, In a typical Logout scenario, you would be removing the tokens from tokenstore itself. [tokenStore.removeAccessToken(accessToken), tokenStore.removeRefreshToken(refreshToken);]. Token values can be retrieved from Authorization-header.

  • Astropcr

    Hey there,

    The zip file downloaded does not contain a web.xml file or did I get a corrupted file. Is that intended? If so, when I deploy to JBoss EAP 7 (with Undertow web component) it doesn’t seem to map to any URL and I get a 404 from the /user/ endpoint. When I adapted the examples into my own project I was getting the Client Authentication issue mentioned by Prateek Gupta. Any help about how to define and control the RESTEasy and Spring servlets would be appreciated.

  • Shahid

    can somebody give me the same project in xml configuration? @websystique:disqus

  • ismailzakky

    nice article websystique. but i have a question, can i add user information inside the token access, something like user_id?

  • Prateek Gupta

    hey websystique. need help with the ldap implementation of this. Unable to define my own configuration for ldap integration.

  • Shahid

    Please tell me, How can i add users from db??.. instead of bill and bob @websystique

  • Shahid

    hello, please give me the spring-config.xml file.. @websystique

    • websystique

      Hello Shahid, this is pure annotation based project, no xml.I would recommend if possible to move to annotation based approach unless you are constrained by legacy stuff.

      • Shahid

        Please can you give me some link of examples done using xml

  • JANMEJAYA DAS

    Getting below exception while deploying in tomcat:
    Exception encountered during context initialization – cancelling refresh attempt
    org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [in.jay.configuration.HelloWorldConfiguration]; nested exception is java.io.FileNotFoundException: class path resource [org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerConfigurerAdapter.class] cannot be opened because it does not exist

    • websystique

      Hi DAS,
      Seems your project dependencies are not being resolved. You should not get this unless you are using a Spring Security version which does not have this class. Assuming you are using the same or higher spring- version, you should perform a “mvn clean package” or build via IDE. In case you are trying to run it from within Eclipse, please have a look at Setup tomcat+Eclipse.

  • Nischal Shakya

    Hello websystique. I had already configure apache tomcat 7 in server runtime enviroment but when i tried to run this project
    i got this problem as shown in the figure how to solve it
    https://uploads.disquscdn.com/images/a06df0e477fd7d5d5132e2f4f3f9b38b1e8b95753237af962cbf90329ad6ca1c.png

    • websystique

      Hi Nischal, seems your IDE is creating this creepy issue. Have a look at this StackOverflow link, seems you are not alone, and there is a solution.

  • Pingback: Hibernate One-To-One Unidirectional with Foreign Key Associations (Annotation) - WebSystique()

  • Pingback: Hibernate Many-To-Many Unidirectional ( Annotation) - WebSystique()

  • shaiwal mallick

    How can we convert this project into a gradle project ?

  • Prateek Gupta

    hi @websystique:disqus

    When i m trying to hit with postman i am getting the error There is no client authentication. Try adding an appropriate authentication filter. When i debugged the code I found that the principal object is getting set as null which is why its getting the exception. Any help?

    • websystique

      Hi Prateek, sorry i missed this message. I’ve tested this example extensively on postman. In case you can still reproduce it, share me the class/line-number where you see the principal object being set to null.Thanks.

      • Ged

        Hi @websystique:disqus,

        I agree with @disqus_80AnYdujgk:disqus. I have followed your example and all worked great. However, when i attempted to go beyond what is show on this page, i.e i attempted to inject principal into my controller, then principal was set to null each time.

        @RequestMapping(method = RequestMethod.GET)
        public ResponseEntity user(Principal principal){
        System.out.ptintln(principal.getName()); //always returns null
        }

        However if i attempt to get principal using below, it works fine
        SecurityContextHolder.getContext().getAuthentication().getName()

        I wonder what is missing in the above configuration that Principal does not get injected in the controllers?

        • Almiriad

          Hello,

          Have you found a solution to this problem ?, I’m facing the same issue.

          Thanks.

          • Ged

            Hi Almiriad, it was my own misunderstanding of how OAuth2 works. If you follow this example precisely it will work. However please note (this is what i missed out) that Principal is only injected if the access_token parameter is present in the url parameters of ANY url that you invoke. access_token has a link back to your user and once its present in the url then principal is injected else principal is null.

          • Almiriad

            Hi @zalys:disqus thanks for the info, that seems quite logic but my problem is that I have the problem upon token request when I provide grant_type=password with all mycredentials needed.

            To explain in a bit more details, I have followed this tuto and adapted it to use a JDBC token store and a custom user client service to generate the principal’s priviledge.

            When I tested it with Insomnia (a REST client)everyhting was OK, but when I tested it with a simple HTML/JS app then I had a CORS error.

            I followed different recommendations found on stackoverflow that made me adapt the CORS filter I had set-up, but now I have this problem “There is no client authentication. Try adding an appropriate authentication filter.”

            I have no doubt that I have missed a step somewhere but I can’t find what I’ve done wrong so far and I was wondering if you or@exit196:disqus had found a solution.

    • Exit196

      I have the same problem. Download sources and look at com.websystique.springmvc.configuration package. There is CORSFilter.java. I think this may be important in this case. @websystique:disqus how to configure this using web.xml?

      • Exit196

        I found solution: missing class SecurityWebApplicationInitializer.

        • Andrew

          For anyone else who comes this way, that class is simply:
          ….
          import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

          public class SecurityWebApplicationInitializer
          extends AbstractSecurityWebApplicationInitializer {

          }

  • Anton Chertash

    Insane. Send a client credentials in URL params….
    I wanna to send client creds in POST-body without any basic authorization header. How to do that?

    • websystique

      Any security related stuff should use HTTPS. and once you use that, it is all but insane. BTW, on your question, if you are sending the client-credentials in body, then you are in-fact just sending something in the body and the server must know that whatever you are sending in body also includes credentials.This is the proprietary stuff. There is a reason why authorization-header is defined in HTTP.

  • Hari Anirudh

    Hi @websystique:disqus ,
    I imported the source code and tried running it on my local, but I’m getting this error displayed when I ran the Spring Rest Client.
    Exception in thread “main” org.springframework.web.client.ResourceAccessException: I/O error on POST request for “http://localhost:8080/SpringSecurityOAuth2Example/oauth/token”: Connection refused: connect; nested exception is java.net.ConnectException: Connection refused: connect

    What could be the fix? I checked http://stackoverflow.com/questions/11648706/spring-resttemplate-client-connection-refused-exception but couldn’t find a solution.

    • websystique

      H Hari,
      /oauth/token endpoint is used to get the refresh/access token and expects mentioned query parameters, you would need to provide then in order to get the tokens to be used with future requests.

      • Hari Anirudh

        Sorry for my lack of understanding but could you please elaborate? I
        thought the grant type, username and password are already specified. Is
        there something I am missing here?

        Thanks for your help.

        • Alex @ i-telligence

          I’m getting the same problem: 401 null when I run the SpringRestClient:

          10:49:34.812 [main] DEBUG org.springframework.web.client.RestTemplate – Created POST request for “http://localhost:8080/SpringSecurityOAuth2Example/oauth/token?grant_type=password&username=bill&password=abc123″
          10:49:34.843 [main] DEBUG org.springframework.web.client.RestTemplate – Setting request Accept header to [application/xml, text/xml, application/json, application/*+xml, application/*+json]
          10:49:34.997 [main] DEBUG org.springframework.web.client.RestTemplate – POST request for “http://localhost:8080/SpringSecurityOAuth2Example/oauth/token?grant_type=password&username=bill&password=abc123″ resulted in 401 (null); invoking error handler
          Exception in thread “main” org.springframework.web.client.HttpClientErrorException: 401 null

          When use Postman:

          {
          “timestamp”: 1480673827224,
          “status”: 401,
          “error”: “Unauthorized”,
          “message”: “Bad credentials”,
          “path”: “/SpringSecurityOAuth2Example/oauth/token”
          }

          Have you had any luck in getting it to run?

          • websystique

            Hi Alex, are you sending the client-credentials in Auth header as shown in here?

          • Hari Anirudh

            Hi Alex,

            Nope. Haven’t had much luck although I was a bit busy with other things of late. Let me know if you find a fix.

            And Websystique, you mean in the getHeadersWithClientCredentials() method right? If so, yes I didn’t make any changes to the RestClient class that you have used, as you seem to have been sending the client credentials already. Have I grossly overlooked something? Thanks for your time and hope you can help.

  • Paco Parra

    Life saver, thanks!

  • Thanushan Mackmilan Selvaratna

    Hi @websystique:disqus ,

    I have implemented using UserDetailsService instead of using in memory,but when i access http://localhost:8080/MediaConceptsSecurity/user/?access_token=b8f089ef-eaf6-43fb-83af-e150e8c01ce1 im getting
    access_denied
    Access is denied

    please advice me should i need to change anything in your current code?

    Thanks.

    • websystique

      Hi, Selvaratna, Is your ResourceConfiguration class is same as shown in this post? Could you also explain how exactly did you configure with UserDetailsService? This example is well tested, so i suspect the changes for UserDetailsService having some issue.

      • Thanushan Mackmilan Selvaratna

        Hi @websystique:disqus ,

        Thanks a lot for your immediate reply,now that problem is solved.
        actually the problem was,i provided the role name as ADMIN but springs security its changing as ROLE_ADMIN.
        now i changed my service as well,its working fine.
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        User user=getUserByName(username);
        SimpleGrantedAuthority authority=new SimpleGrantedAuthority(“ROLE_ADMIN”);

        List authorities = Arrays.asList(authority);

        return new org.springframework.security.core.userdetails
        .User(user.getUsername(), user.getPassword(), authorities);
        }

        • websystique

          Hi Selvaratna, This was a nasty one. Glad you nailed it. Your answer will certainly help others.

          • Thanushan Mackmilan Selvaratna

            Hi @websystique:disqus,

            does it give any problem when using https?

          • websystique

            For https you might need to add extra configuration [requiresChannel()]. Have a look at Document : Enforcing SSL.

          • Thanushan Mackmilan Selvaratna

            Thanks lot for your response,
            I got some issues when I try to get tokens,because my server ssl enabled.
            When I try to get token it’s reached page not found.

          • websystique

            Hi Selvaratna, did you update URL to use https?

  • Thanushan Mackmilan Selvaratna

    Hi @websystique:disqus ,

    It’s awesome tutorial,you simply reduce my work :)
    thanks a lot

  • Pingback: Spring 4+JMS+ActiveMQ example with @JmsListener & @EnableJms - WebSystique()

  • Pingback: Spring 4 + Quartz Scheduler Integration Example - WebSystique()

  • Pingback: Spring Job Scheduling using TaskScheduler (XML Config) - WebSystique()

  • Pingback: Spring 4 + Hibernate 4 + MySQL+ Maven Integration example (Annotations+XML) - WebSystique()

  • Pingback: Spring @PropertySource & @Value annotations example - WebSystique()

  • Pingback: Spring Auto-detection autowire & Component-scanning Example With Annotations - WebSystique()

  • Pingback: Spring Dependency Injection Example with Constructor and Property Setter (XML) - WebSystique()

  • Pingback: Spring 4 Hello World Example - WebSystique()

  • Pingback: Spring Security 4 Secure View Fragments using taglibs - WebSystique()

  • Pingback: AngularJS+Spring Security using Basic Authentication - WebSystique()

  • Pingback: Spring MVC 4 + Spring Security 4 + Hibernate Example - WebSystique()

  • Pingback: Spring 4 MVC+JPA2+Hibernate Many-to-many-Example - WebSystique()

  • Pingback: Spring MVC 4 FileUpload-Download Hibernate+MySQL Example - WebSystique()

  • Pingback: Spring MVC 4 File Upload Example using Commons fileupload - WebSystique()

  • Pingback: Spring MVC 4 File Download Example - WebSystique()

  • Pingback: Spring 4 MVC + JMS + ActiveMQ annotation based Example - WebSystique()

  • Pingback: Spring 4 MVC+Hibernate 4+MySQL+Maven integration + Testing example using annotations - WebSystique()

  • Pingback: Spring 4 MVC+Hibernate Many-to-many JSP Example with annotation - WebSystique()

  • Pingback: Spring 4 MVC+AngularJS Routing Example using UI-Router - WebSystique()

  • Pingback: Spring 4 MVC+AngularJS Routing Example using ngRoute - WebSystique()

  • Pingback: Spring MVC @RequestBody @ResponseBody Example - WebSystique()

  • Pingback: Spring MVC 4 RESTFul Web Services CRUD Example+RestTemplate - WebSystique()

  • Pingback: Spring 4 MVC REST Service Example using @RestController - WebSystique()

  • Pingback: Spring 4 MVC ContentNegotiatingViewResolver example - WebSystique()

  • Юра Деркач

    Thanks! Your app works great!!!
    But my question is: how to make “add an authorization header with client credentials [my-trusted-client/secret]” using url. Because, I try to use mobile application to authentication.

    • websystique

      Hi, You can add the stuff you sent in your Authorization header to your URL, something like https://myclientid:myclientsecret@www.yoursite.com/. However it is not widely recommend over Authorization header as it exposes your id,password [not encoded] right in URL.Of course using SSL is an option as everything will be encrypted then. Using Authorization header + SSL seems to be a preferable solution.

  • http://www.tinmegali.com Tin Megali

    Hello @websystique:disqus, outstanding tutorial.
    I developed an Android client for this server using Dagger2 and Retrofit. I’ll leave the link here, maybe it helps somebody out there.
    https://github.com/tinmegali/android_restapi_oauth
    And again, thank you for the excellent explanation about this topic. =)

    • websystique

      Good job Tin.

  • Seeebastian

    Hi @websystique:disqus , I try to implement it with custom details service.

    I changed

    @Autowired
    public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
    .withUser(“bill”).password(“abc123″).roles(“ADMIN”).and()
    .withUser(“bob”).password(“abc123″).roles(“USER”);
    }

    to

    @Autowired
    public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {

    auth.userDetailsService(myUserDetailsService);
    }

    And unfortunately, when loadUserByUsername method is calling, then I get the exception:

    unauthorized
    Could not obtain transaction-synchronized Session for current thread

    I added transactional annotation. I think is should be cause by configuration. Could you help with my problem or show how to implement it with own details service. Thanks you in advance.

    • websystique

      Hi Seeebastian, It seems to be a transaction issue. As shown in this post, you should add @Transactional:

      @Transactional(readOnly=true)
      public UserDetails loadUserByUsername(String ssoId)
      throws UsernameNotFoundException {
      User user = userService.findBySso(ssoId);
      System.out.println(“User : “+user);
      if(user==null){
      System.out.println(“User not found”);
      throw new UsernameNotFoundException(“Username not found”);
      }
      return new org.springframework.security.core.userdetails.User(user.getSsoId(), user.getPassword(),
      user.getState().equals(“Active”), true, true, true, getGrantedAuthorities(user));
      }

      Let me know If it still does not work.

      • Seeebastian

        Hi @websystique:disqus,

        I learn from your tutorials and I made it as in the post which you are mentioned, unfortunately it does not work:

        Service(“MyUserDetailsService”)
        public class MyUserDetailsService implements UserDetailsService {

        @Autowired
        UserDao userDaoImpl;

        @Transactional(readOnly=true)
        @Override
        public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {

        System.out.println(“I am here ” + login);

        User user = userDaoImpl.findByLogin(“seba”);
        System.out.println(“I am here 2″ + user.getName());

        if(user == null) {
        System.out.println(“User was not found “);
        throw new UsernameNotFoundException(login);
        } else {
        System.out.println(“GREAT!”);
        new org.springframework.security.core.userdetails.User(user.getLogin(), user.getPass(), getUserRole(user));
        }

        return null;
        }

        What is more the method from userDaoImpl works in my restController. So I think, it can be caused by OAuth2 security. It seems strange, like something from oauth security would be blocking obtaining the transaction. Thank you for interest in my problem.

        • websystique

          Hi Seebastian, Do you have your project somewhere on github? I don’t see any issue and it should have worked.

          • kasan kulasegaram

            He is using sessionFactory.getCurrentSession()..if he put sessionFactory.openSession() it will works

    • Thanushan Mackmilan Selvaratna

      Hi @disqus_znCXpyFh7d:disqus,

      did u managed to solve above mentioned issue?

      thanks.

  • Pingback: Spring oauth2 – difference between authorization service and globalUserDetails | Web Coder()

  • Ranjith Thota

    Hi Websystique,

    http://localhost:8080/SpringSecurityOAuth2Example/oauth/token?grant_type=password&username=bill&password=abc123

    From above api
    We need to send username and password in encrypted format, is it possible ?
    How OAuth2 Authentication server recognised login user details ?

    • websystique

      Hi Ranjith,

      This is indeed an interesting question and i took my time. After exploring a bit on the way to do that, i came across this discussion which gives a clue about using PasswordEncoder in AuthenticationManager [On Server side]. It also touches a bit on encryption on client side using.Let me know if it can help.Else i will try to post a working code for it.

      • Ranjith Thota

        Thanks for reply……!

        We already implemented PasswordEncoder on server side for store the password in encrypted format.But we need client side encryption.
        Please share a working code for my above question.

  • Sof Ham

    Hi, thank you for this excellent tutorial. I used you classes in spring boot rest project using oauth2.
    I’m getting this stack : Caused by: java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling

    • websystique

      Hi Sof,

      This project is not spring-boot based, but from the error description it seems that you are missing a basic app configuration. Could you please double check your @Configuration classes if you have a clash with some stuff which is web specific and for that you may need a web-configurations iso @Confguration?

  • Pingback: Spring Security + OAuth2 – { Desarrollo JAVA }()

  • Nikhil Srivastava

    Hi websystique,
    The project downloaded refers to a different build

  • Hicham

    Hi Websystique,
    How can i use the Client Credentials with an application based o spring security,REST and angularJS

    • websystique

      Hi Hicham, Sorry for being late. In client credentials, you posses the client credentials and send them to server in order to ask the access token. You may use the same approach as shown here, sending the credentials in Auth header[should be used with SSL].Look at AngularJS+Spring Security using Basic Authentication, will help you.

  • Manisha Sathe

    First of all thanks for wonderful article. It really works. I made one small change

    Instead of InMemoryAuthentication:

    @Autowired
    public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
    .withUser(“bill”).password(“abc123″).roles(“ADMIN”).and()
    .withUser(“bob”).password(“abc123″).roles(“USER”);
    }

    I tried to use my CustomUserDetails

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(customerUserDetailsService);
    }

    I get access token (with user name & password fetched from database). I can access my secured resource with this access token. After timeout I get proper invalid access token error. But when I try to get new access token using refresh token I get following error

    http://localhost:9090/springjpabootproj/oauth/token?grant_type=refresh_token&refresh_token=949264ba-9d92-42fc-9e66-f28c7cc39304
    {
    “error”: “server_error”,
    “error_description”: “UserDetailsService is required.”
    }

    What is missing ? Please help. Thanks in advance.

  • Hicham

    i have an application that the user(Admin) autenticate with a form and when he’s successfully login into the application , he can do the CRUD operations on the list of users with a RESTful API, can i use OAUTH2 to secure this page only , i’ve been using Basic Auth , but it’s not interesting i should with every request send the (login : admin, password : 123 ) with an angularJS interceptor; i use AngularJS for the front-end , and this application is based on your tutorials( spring , hibernate,angularJS,Spring security .. ) thanks , i would know how can i secure my api if that possible ( i’m just begginer in spring )

  • Daniel Wong

    Hello Websystique,

    May I know why use different version for spring core and spring security ?

    4.3.1.RELEASE
    4.1.1.RELEASE

    Would it have problem if I use 4.3.1.RELEASE as springsecurity version ?

    Thank you

    • websystique

      Hey Daniel, Spring and spring security are different projects, evolving independently, that’s why you see different versions for them..At this moment, the latest spring security version is 4.1.3.RELEASE You may want to upgrade to latest version for both Spring and Spring Security.

  • Dhyanandra Singh

    Hello Websystique,
    I want to add extra information like role etc with token information after successful login.
    How can i customize this default response.

    • websystique

      Hi Dhyanandra, ResourceServerConfiguration configure method is the right place for these settings.

  • Jesus Rafael Lopez Ibarra

    Hello, great articles, i’ve been studying them from a few weeks

    In this one , i’ve got this error:

    09:59:47,397 ERROR [org.springframework.web.context.ContextLoader] (ServerService Thread Pool — 132)
    Context initialization failed: org.springframework.beans.factory.BeanCreationException: Error creating bean with name
    ‘springSecurityFilterChain’ defined in class path resource
    [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]:
    Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException:
    Failed to instantiate [javax.servlet.Filter]: Factory method ‘springSecurityFilterChain’ threw exception; nested exception
    is java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.SerializationConfig.withDefaultPrettyPrinter
    (Lcom/fasterxml/jackson/core/PrettyPrinter;)Lcom/fasterxml/jackson/databind/SerializationConfig;

    I dunno what it could be , am i the only one with this errror?

    I’m using wildfly 10, Java 8 , and Eclipse STS , i’m not sure if it is about environment or anything else,

    thanks in advance =D

    • websystique

      Hi, Seems you have more than one version of Jackson in your class-path. Check the dependency tree in your IDE[or commandline] and get rid of one of them [or exclude one of them manually in pom.xml ]. The latest version [if you want to use] is shown below, it contains withDefaultPrettyPrinter method:

      com.fasterxml.jackson.core
      jackson-databind
      2.7.5

      • Hân Siro

        Hi @websystique:disqus : i take the same error org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named ‘springSecurityFilterChain’ is defined . I try search in stackoverflow and add more in file web.xml :

        springSecurityFilterChain
        org.springframework.web.filter.DelegatingFilterProxy

        i get :

        java.lang.RuntimeException: java.lang.IllegalStateException: Duplicate Filter registration for ‘springSecurityFilterChain’

        how i can fix it to implement oauth2 in my app.

  • Dhyanandra Singh

    Hi,
    Its nice really work.
    can you please post another example with oauth2 and jdbc token store and jwt.

  • Rahul Bhalla

    Hi
    You did excellent work by giving working example of Oauth2.
    I have few query as I modified your example.
    1. Modified a method of class ResourceServerConfiguration to

    public void configure(HttpSecurity http) throws Exception {
    http.
    anonymous().disable()
    .authorizeRequests()
    .antMatchers(“/user/**”).fullyAuthenticated()
    //.antMatchers(“/user/**”).access(“hasRole(‘ADMIN’)”)
    .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
    }

    Now the result (access_token) of refresh token allow to use rest Api to user without calling request for access token using refresh_token .

    2. I am using spring security oauth2 XML from one of my project which allow to pass the client credentials as query parameter (http://localhost:8080/SpringSecurityOAuth2Example/oauth/token?grant_type=password&username=bill&password=abc123&client_id=client&client_secret=123)
    but with this configuration, forces me pass it in header. What are the changes required.

    kindly revert back

    • websystique

      Hi Rahul,

      1)If you see the RestTemplate example i mentioned above, i do not send the refresh token request at all [?grant_type=password iso grant_type=refresh_token].You do get the access token even the very first time along with refresh-token which you can then use it. However that access-token will expire and to get another one, you should be using refresh-token.

      2) We are sending Authorization header containing client-credentials because by default URL /oauth/token is protected using HTTP Basic Authentication.

      //AuthorizationServerSecurityConfigurer
      @Override
      public void configure(HttpSecurity http) throws Exception {

      // ensure this is initialized
      frameworkEndpointHandlerMapping();
      if (allowFormAuthenticationForClients) {
      clientCredentialsTokenEndpointFilter(http);
      }

      for (Filter filter : tokenEndpointAuthenticationFilters) {
      http.addFilterBefore(filter, BasicAuthenticationFilter.class);
      }

      http.exceptionHandling().accessDeniedHandler(accessDeniedHandler);
      if (sslOnly) {
      http.requiresChannel().anyRequest().requiresSecure();
      }

      }

      It is recommend to use HTTP basic authentication. But if you want to use request parameters/query parameters, you can create your own filter and add that filter by overriding following method of AuthorizationServerSecurityConfigurer

      public void addTokenEndpointAuthenticationFilter(Filter filter) {
      this.tokenEndpointAuthenticationFilters.add(filter);
      }

      Note: clientCredentialsTokenEndpointFilter [used for form-based authentication] is an example of filter which takes into account request parameters and can be enabled by

      @Override
      public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
      oauthServer.allowFormAuthenticationForClients();
      }

      • Rachit Kakkar

        Hi
        I am getting resource not found error for http://localhost:8080/SpringSecurityOAuth2Example/user/ and i tried to debug, but no use.

        • websystique

          Hi Rachit, In case you are running this example from within eclipse with embedded tomcat, t could be related to your tomcat+Eclipse setup. Have a look at this post.

          • Rachit Kakkar

            I tried the same before and also i tried running a rest test app without using spring annotations and it ran fine.(Took it fromhttp://www.mkyong.com/webservices/jax-rs/jax-rs-queryparam-example/
            ).Also attached the success screenshot.But when i took this app posted ,imported as a maven project.I got the error as in the screenshot.

          • Rachit Kakkar

            Also the other example of crud rest service throwing same error.May be spring annotations are not getting accepted …I am using tomcat 8 .

          • Rachit Kakkar

            Hi Sir,

            It has started working after i changed the version in project facet core. xml.Previously it was 2.3, so pom had errors.
            Thanks for the help !!!!

  • Pingback: Spring 4 MVC+AngularJS CRUD Example using $http service - WebSystique()

  • Pingback: Hibernate Many-To-Many Bidirectional (Annotation) - WebSystique()

  • Pingback: Hibernate One-To-One Unidirectional with Shared Primary Key (Annotation) - WebSystique()

  • Pingback: Hibernate MySQL Maven Hello World Example (Annotation) - WebSystique()

  • Pingback: Hibernate MySQL Maven Hello World Example (XML) - WebSystique()

  • Pingback: Spring Batch- Read a CSV file and write to an XML file - WebSystique()

  • Pingback: Spring Batch- Read an XML file and write to a CSV file - WebSystique()

  • Pingback: Spring Batch- Read From MySQL database & write to CSV file - WebSystique()

  • Pingback: Spring Batch- MultiResourceItemReader & HibernateItemWriter example - WebSystique()

  • Pingback: Spring Batch & Quartz Scheduler Example (Tasklet usage) - WebSystique()

  • Pingback: Spring Security 4 Hibernate Integration Annotation+XML Example - WebSystique()

  • Pingback: Spring Security 4 Hibernate Password Encoder Bcrypt Example - WebSystique()

  • Pingback: Spring Security 4 Method security using @PreAuthorize,@PostAuthorize, @Secured, EL - WebSystique()

  • Pingback: Spring Security 4 Hibernate Role Based Login Example - WebSystique()

  • Pingback: Spring Security 4 Role Based Login Example - WebSystique()

  • Pingback: Spring Security 4 Custom Login Form Annotation+XML Example - WebSystique()

  • Pingback: Spring Security 4 Hello World Annotation+XML Example - WebSystique()

  • Pingback: Spring MVC 4 File Upload Example using Servlet 3 MultiPartConfigElement - WebSystique()

  • Pingback: Spring 4 MVC+Hibernate 4+MySQL+Maven integration example using annotations - WebSystique()

  • Pingback: Spring 4 MVC+AngularJS CRUD Application using ngResource - WebSystique()

  • Pingback: Spring 4 MVC+Apache Tiles 3 Example - WebSystique()

  • Pingback: Spring 4 MVC Form Validation and Resource Handling (Annotations) - WebSystique()

  • Pingback: Spring 4 MVC HelloWorld Tutorial - Annotation/JavaConfig Example - WebSystique()

  • Pingback: Spring 4 MVC HelloWorld Tutorial - Full XML Example - WebSystique()

  • Pingback: Spring Dependency Injection Annotation Example, Beans Auto-wiring using @Autowired, @Qualifier & @Resource Annotations Configuration - WebSystique()

  • Pingback: Spring @Profile Example - WebSystique()

  • Pingback: Spring Job Scheduling with @Scheduled & @EnableScheduling Annotations - WebSystique()

  • Pingback: Spring 4+JMS+ActiveMQ Example with Annotations - WebSystique()

  • Pingback: Spring 4 Email Integration Tutorial - WebSystique()

  • Pingback: Spring 4 Email With Attachment Tutorial - WebSystique()

  • Pingback: Spring 4 Email using Velocity,Freemarker Template library - WebSystique()

  • Pingback: Secure Spring REST API using Basic Authentication - WebSystique()