This tutorial shows how to set up a OAuth2 service to protect rest resources. Source code download GitHub. (https://github.com/iainporter/oauth2-provider) You can download the source code and start writing a service that is protected by the OAuth method. This source contains features:
* User Registration and Login
* Email Verification
* Password lost
The following techniques have been adopted:
* OAuth2 Protocol
* Spring Security
* Spring Integration
* Spring Data
* Jersey/jax-rs
* Gradle/groovy
* MongoDB
Build your project in the following ways:
> Git clone [email protected]:iainporter/oauth2-provider.git
> CD Oauth2-provider
>./gradlew Clean Build Integrationtest
To run the Web project:
This application is based on MongoDB as the persistence layer, before running the application to confirm that Mongod is running on port 27017.
To run the command:
>./gradlew tomcatrun
Open http://localhost:8080/oauth2-provider/index.html in Browser
1. Create a User:
Curl-v-X POST \
-h "Content-type:application/json" \
-H "Authorization:basic mzuzyjmwmmm0ndu3ngy1njuwndu2oddlntm0ztdknme6mjg2oti0njk3ztyxnwe2nzjhnjq2ytq5mzu0nty0nmm= " \
-d ' {"user": {"EmailAddress": "[email protected]"}, "password": "Password"} ' \
' Http://localhost:8080/oauth2-provider/v1.0/users '
The result should be:
{"Apiuser":
{"EmailAddress": "[email protected]",
"FirstName": null,
"LastName": null,
"Age": null,
"id": "8a34d009-3558-4c8c-a8da-1ad2b2a393c7",
"Name": "[email protected]"},
"Oauth2accesstoken":
{"Access_token": "7e0e4708-7837-4a7e-9f87-81c6429b02ac",
"Token_type": "Bearer",
"Refresh_token": "D0f248ab-e30f-4a85-860c-bd1e388a39b5",
"Expires_in": 5183999,
"Scope": "Read Write"
}
}
2. Request an Access token:
Curl-v-X POST \
-h "Content-type:application/json" \
-H "Authorization:basic mzuzyjmwmmm0ndu3ngy1njuwndu2oddlntm0ztdknme6mjg2oti0njk3ztyxnwe2nzjhnjq2ytq5mzu0nty0nmm= " \
' Http://localhost:8080/oauth2-provider/oauth/token?grant_type=password&[email protected]&password= Password
The result should be:
{
"Access_token": "a838780e-35ef-4bd5-92c0-07a45aa74948",
"Token_type": "Bearer",
"Refresh_token": "AB06022F-247C-450A-A11E-2FFAB116E3DC",
"Expires_in": 5183999
}
3. Refresh a token:
Curl-v-X POST \
-h "Content-type:application/json" \
-H "Authorization:basic mzuzyjmwmmm0ndu3ngy1njuwndu2oddlntm0ztdknme6mjg2oti0njk3ztyxnwe2nzjhnjq2ytq5mzu0nty0nmm= " \
' Http://localhost:8080/oauth2-provider/oauth/token?grant_type=refresh_token&refresh_token= AB06022F-247C-450A-A11E-2FFAB116E3DC '
The result should be:
{
"Access_token": "4835cd11-8bb7-4b76-b857-55c6e7f36fc4",
"Token_type": "Bearer",
"Refresh_token": "AB06022F-247C-450A-A11E-2FFAB116E3DC",
"Expires_in": 5183999
}
Web Context
A jersey handles all resource calls:
- <servlet-mapping>
- <servlet-name>jersey-servlet</servlet-name>
- <url-pattern>/*</url-pattern>
- </servlet-mapping>
The Spring servlet handles all OAuth calls:
- <servlet-mapping>
- <servlet-name>spring</servlet-name>
- <url-pattern>/oauth/*</url-pattern>
- </servlet-mapping>
Spring security Mates define a filter:
- <filter>
- <filter-name>springSecurityFilterChain</filter-name>
- <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
- <init-param>
- <param-name>contextAttribute</param-name>
- <param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring</param-value>
- </init-param>
- </filter>
To filter all URLs in the root directory:
- <filter-mapping>
- <filter-name>springSecurityFilterChain</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
Configuring the OAuth Process
- <oauth:authorization-server client-details-service-ref= "Client-details-service" token-services-ref= " Tokenservices ">
- <oauth:refresh-token/>
- <oauth:password/>
- </oauth:authorization-server>
The default token endpoint is/oauth/token, with only password flow and refresh token support.
Protect token Endpoints
To protect the token endpoint with spring security:
-
- xmlns= "Http://www.springframework.org/schema/security" >
- <anonymous enabled= "false"/>
-
- <access-denied-handler ref= "Oauthaccessdeniedhandler"/>
-
The following configuration authorizes the Authentication manager and Client services:
- <bean id= "Clientcredentialstokenendpointfilter"
- class= "Org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter" >
- <property name= "AuthenticationManager" ref= "Clientauthenticationmanager"/>
- </bean>
- <authentication-manager id= "Clientauthenticationmanager" xmlns= "http://www.springframework.org/schema/security" >
- <authentication-provider user-service-ref= "Client-details-user-service"/>
- </authentication-manager>
- <bean id= "Client-details-user-service" class= " Org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService ">
- <constructor-arg ref= "Client-details-service"/>
- </bean>
Configure the User licensing service
Resource Owner Password Flow needs to manage the user's Authorization Manager
- <bean id= "Passwordencoder" class= "Org.springframework.security.crypto.password.StandardPasswordEncoder"/>
- <sec:authentication-manager alias= "Userauthenticationmanager" >
- <sec:authentication-provider user-service-ref= "UserService" >
- <sec:password-encoder ref= "Passwordencoder"/>
- </sec:authentication-provider>
- </sec:authentication-manager>
The password Password encoder is used to encrypt the password. User Services must implement a userdetailsservice that can be returned to users based on their user name.
- @Override
- Public userdetails Loaduserbyusername (String username) throws Usernamenotfoundexception {
- Notnull (username, "Mandatory argument ' username ' missing.");
- User user = Userrepository.findbyemailaddress (username.tolowercase ());
- if (user = = null) {
- throw new Authenticationexception ();
- }
- return user;
- }
Configure token Service
- <bean id= "tokenservices" class= "Org.springframework.security.oauth2.provider.token.DefaultTokenServices" >
- <property name= "Tokenstore" ref= "Tokenstore"/>
- <property name= "Supportrefreshtoken" value= "true"/>
- <property name= "Clientdetailsservice" ref= "Client-details-service"/>
- </bean>
Securing Resource access
- <oauth:resource-server id= "Resourceserverfilter" token-services-ref= "Tokenservices"/>
Core Services
This service provides information based on access tokens for users. URL format:
/v1.0/users/{id}/someresource
- @Path ("/v1.0/me")
- @Component
- @Produces ({Mediatype.application_json})
- @Consumes ({Mediatype.application_json})
- public class Meresource extends BaseResource {
- @RolesAllowed ({"Role_user"})
- @GET
- Public Apiuser getUser (final @Context securitycontext SecurityContext) {
- User Requestinguser = Loaduserfromsecuritycontext (SecurityContext);
- if (Requestinguser = = null) {
- throw new Usernotfoundexception ();
- }
- return new Apiuser (Requestinguser);
- }
- Protected User Loaduserfromsecuritycontext (SecurityContext securitycontext) {
- Oauth2authentication Requestinguser = (oauth2authentication) securitycontext.getuserprincipal ();
- Object principal = Requestinguser.getuserauthentication (). Getprincipal ();
- User user = null;
- if (principal instanceof User) {
- user = (user) principal;
- } else {
- user = Userrepository.findbyemailaddress ((String) principal);
- }
- return user;
- }
- }
To test this application, start:
>./gradlew tomcatrun
Test:
Curl-v-X GET \
-h "Content-type:application/json" \
-H "Authorization:bearer [your token here]" \
' Http://localhost:8080/oauth2-provider/v1.0/me '
Reference: Https://github.com/tcompiegne/couchbase-token-store-spring-oauth2
Https://github.com/tcompiegne/oauth2-server-spring-couchbase
Transferred from: http://www.jdon.com/dl/best/securing-rest-services-with-spring.html.html
Use spring security and OAuth2 for RESTful service safety certification