├── LICENSE
├── README.md
├── _config.yml
├── authentication
├── .gitignore
├── README.md
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── authentication
│ │ │ ├── Application.java
│ │ │ ├── api
│ │ │ └── AuthenticationAPI.java
│ │ │ ├── config
│ │ │ ├── AuthorizationServerConfig.java
│ │ │ ├── PersistentContext.java
│ │ │ ├── ResourceServerConfiguration.java
│ │ │ ├── SwaggerConfig.java
│ │ │ ├── WebSecurityConfig.java
│ │ │ └── package-info.java
│ │ │ ├── model
│ │ │ ├── User.java
│ │ │ └── UserTokenSession.java
│ │ │ ├── repository
│ │ │ ├── UserRepository.java
│ │ │ └── UserTokenSessionRepository.java
│ │ │ └── service
│ │ │ ├── UserDetailsServiceImpl.java
│ │ │ ├── UserTokenSessionService.java
│ │ │ └── UserTokenSessionServiceImpl.java
│ └── resources
│ │ ├── application.properties
│ │ ├── data.sql
│ │ ├── images
│ │ ├── Swagger-UI-Home.png
│ │ ├── Swagger-ui-auth.png
│ │ ├── swagger-ui-login-token.png
│ │ └── swagger-ui-login.png
│ │ └── schema.sql
│ └── test
│ ├── java
│ └── com
│ │ └── authentication
│ │ ├── api
│ │ ├── AuthenticationAPITest.java
│ │ └── OAuthHelper.java
│ │ └── service
│ │ ├── UserDetailsServiceTest.java
│ │ └── UserTokenSessionServiceTest.java
│ └── resources
│ └── application.properties
└── oauthswager
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Rohit Kumar
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # spring-boot-oauth2-jwt-swagger-ui
2 | Spring Boot , OAuth 2 , JWT (Json Web Token) and Swagger UI
3 |
4 | # Spring Boot + OAuth 2.0 + JWT + Swagger-UI 2?
5 |
6 | ## How to start ?
7 |
8 | ```
9 | $ mvn spring-boot:run
10 | ```
11 |
12 | ## Swagger-UI
13 | * After starting the application Click on [Swagger-home](http://localhost:8080/api/swagger-ui.html)
14 |
15 | 
16 |
17 |
18 | ## User Data
19 |
20 | ```
21 | user-name | password
22 | user1@example.com | password
23 | user2@example.com | password
24 | user3@example.com | password
25 | ```
26 |
27 |
28 | ## Authorize
29 | * Use above given user details to login and generate the authorization token.
30 | 
31 |
32 | 
33 |
34 | * Login using the generated token
35 | 
36 |
37 |
38 |
39 | ## Change OAuth configuration
40 | * Edit the configuration in the file [application.properties](/authentication/src/main/resources/application.properties)
41 |
42 | ```
43 | server.port=8080
44 | server.contextPath=/api
45 |
46 | logging.level.com.alfred=DEBUG
47 |
48 | # Data source properties
49 | spring.jpa.hibernate.ddl-auto=validate
50 | spring.jpa.show-sql=true
51 |
52 | # openssl genrsa -out jwt.pem 2048
53 | # openssl rsa -in jwt.pem
54 | config.oauth2.privateKey=MIICXQIBAAKBgQDNQZKqTlO/+2b4ZdhqGJzGBDltb5PZmBz1ALN2YLvt341pH6i5mO1V9cX5Ty1LM70fKfnIoYUP4KCE33dPnC7LkUwE/myh1zM6m8cbL5cYFPyP099thbVxzJkjHWqywvQih/qOOjliomKbM9pxG8Z1dB26hL9dSAZuA8xExjlPmQIDAQABAoGAImnYGU3ApPOVtBf/TOqLfne+2SZX96eVU06myDY3zA4rO3DfbR7CzCLE6qPnyDAIiW0UQBs0oBDdWOnOqz5YaePZu/yrLyj6KM6Q2e9ywRDtDh3ywrSfGpjdSvvoaeL1WesBWsgWv1vFKKvES7ILFLUxKwyCRC2Lgh7aI9GGZfECQQD84m98Yrehhin3fZuRaBNIu348Ci7ZFZmrvyxAIxrV4jBjpACW0RM2BvF5oYM2gOJqIfBOVjmPwUrobYEFcHRvAkEAz8jsfmxsZVwh3Y/Y47BzhKIC5FLaads541jNjVWfrPirljyCy1n4sg3WQH2IEyap3WTP84+csCtsfNfyK7fQdwJBAJNRyobY74cupJYkW5OK4OkXKQQLHp2iosJV/Y5jpQeC3JO/gARcSmfIBbbI66q9zKjtmpPYUXI4tc3PtUEY8QsCQQCcxySyC0sKe6bNzyC+Q8AVvkxiTKWiI5idEr8duhJd589H72Zc2wkMB+a2CEGo+Y5Hjy5cvuph/pG/7Qw7sljnAkAy/feClt1mUEiAcWrHRwcQ71AoA0+21yC9VkqPNrn3w7OEg8gBqPjRlXBNb00QieNeGGSkXOoU6gFschR22Dzy
55 |
56 | # openssl rsa -in jwt.pem -pubout
57 | config.oauth2.publicKey=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNQZKqTlO/+2b4ZdhqGJzGBDltb5PZmBz1ALN2YLvt341pH6i5mO1V9cX5Ty1LM70fKfnIoYUP4KCE33dPnC7LkUwE/myh1zM6m8cbL5cYFPyP099thbVxzJkjHWqywvQih/qOOjliomKbM9pxG8Z1dB26hL9dSAZuA8xExjlPmQIDAQAB
58 |
59 |
60 | #oauth configurations
61 | config.oauth2.tokenTimeout=3600
62 | config.oauth2.resource.id=oauth2-resource
63 | config.oauth2.clientID=client
64 | config.oauth2.clientSecret=secret
65 | security.oauth2.client.grantType=client_credentials
66 | config.oauth2.accessTokenUri=http://localhost:8080/api/oauth/token
67 | config.oauth2.userAuthorizationUri=http://localhost:8080/api/oauth/authorize
68 | config.oauth2.resourceURI= http://localhost:8080/api/oauth/authorize
69 | ```
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-merlot
--------------------------------------------------------------------------------
/authentication/.gitignore:
--------------------------------------------------------------------------------
1 | #target
2 | */target/*
3 | target/*
4 | #intellij-files
5 | *.idea/*
6 | *.iml
7 | *.DS_Store
8 | *-pom.xml
9 | RemoteSystemsTempFiles/*
10 | .svn/*
11 | .settings/
12 | .project
13 | .metadata/
14 | .idea/
15 | .classpath
16 | ../.DS_Store
17 | .idea/libraries/Maven*
--------------------------------------------------------------------------------
/authentication/README.md:
--------------------------------------------------------------------------------
1 | # Spring Boot + OAuth 2.0 + JWT + Swagger-UI 2?
2 |
3 | ## How to start ?
4 |
5 | ```
6 | $ mvn spring-boot:run
7 | ```
8 |
9 | ## Swagger-UI
10 | * After starting the application Click on [Swagger-home](http://localhost:8080/api/swagger-ui.html)
11 |
12 | 
13 |
14 |
15 | ## User Data
16 |
17 | ```
18 | user-name | password
19 | user1@example.com | password
20 | user2@example.com | password
21 | user3@example.com | password
22 | ```
23 |
24 |
25 | ## Authorize
26 | * Use above given user details to login and generate the authorization token.
27 | 
28 |
29 | 
30 |
31 | * Login using the generated token
32 | 
33 |
34 |
35 |
36 | ## Change OAuth configuration
37 | * Edit the configuration in the file [application.properties](/authentication/src/main/resources/application.properties)
38 |
39 | ```
40 | server.port=8080
41 | server.contextPath=/api
42 |
43 | logging.level.com.alfred=DEBUG
44 |
45 | # Data source properties
46 | spring.jpa.hibernate.ddl-auto=validate
47 | spring.jpa.show-sql=true
48 |
49 | # openssl genrsa -out jwt.pem 2048
50 | # openssl rsa -in jwt.pem
51 | config.oauth2.privateKey=MIICXQIBAAKBgQDNQZKqTlO/+2b4ZdhqGJzGBDltb5PZmBz1ALN2YLvt341pH6i5mO1V9cX5Ty1LM70fKfnIoYUP4KCE33dPnC7LkUwE/myh1zM6m8cbL5cYFPyP099thbVxzJkjHWqywvQih/qOOjliomKbM9pxG8Z1dB26hL9dSAZuA8xExjlPmQIDAQABAoGAImnYGU3ApPOVtBf/TOqLfne+2SZX96eVU06myDY3zA4rO3DfbR7CzCLE6qPnyDAIiW0UQBs0oBDdWOnOqz5YaePZu/yrLyj6KM6Q2e9ywRDtDh3ywrSfGpjdSvvoaeL1WesBWsgWv1vFKKvES7ILFLUxKwyCRC2Lgh7aI9GGZfECQQD84m98Yrehhin3fZuRaBNIu348Ci7ZFZmrvyxAIxrV4jBjpACW0RM2BvF5oYM2gOJqIfBOVjmPwUrobYEFcHRvAkEAz8jsfmxsZVwh3Y/Y47BzhKIC5FLaads541jNjVWfrPirljyCy1n4sg3WQH2IEyap3WTP84+csCtsfNfyK7fQdwJBAJNRyobY74cupJYkW5OK4OkXKQQLHp2iosJV/Y5jpQeC3JO/gARcSmfIBbbI66q9zKjtmpPYUXI4tc3PtUEY8QsCQQCcxySyC0sKe6bNzyC+Q8AVvkxiTKWiI5idEr8duhJd589H72Zc2wkMB+a2CEGo+Y5Hjy5cvuph/pG/7Qw7sljnAkAy/feClt1mUEiAcWrHRwcQ71AoA0+21yC9VkqPNrn3w7OEg8gBqPjRlXBNb00QieNeGGSkXOoU6gFschR22Dzy
52 |
53 | # openssl rsa -in jwt.pem -pubout
54 | config.oauth2.publicKey=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNQZKqTlO/+2b4ZdhqGJzGBDltb5PZmBz1ALN2YLvt341pH6i5mO1V9cX5Ty1LM70fKfnIoYUP4KCE33dPnC7LkUwE/myh1zM6m8cbL5cYFPyP099thbVxzJkjHWqywvQih/qOOjliomKbM9pxG8Z1dB26hL9dSAZuA8xExjlPmQIDAQAB
55 |
56 |
57 | #oauth configurations
58 | config.oauth2.tokenTimeout=3600
59 | config.oauth2.resource.id=oauth2-resource
60 | config.oauth2.clientID=client
61 | config.oauth2.clientSecret=secret
62 | security.oauth2.client.grantType=client_credentials
63 | config.oauth2.accessTokenUri=http://localhost:8080/api/oauth/token
64 | config.oauth2.userAuthorizationUri=http://localhost:8080/api/oauth/authorize
65 | config.oauth2.resourceURI= http://localhost:8080/api/oauth/authorize
66 | ```
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/authentication/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 | authentication
7 | authentication-service
8 | 0.0.1-SNAPSHOT
9 | Authentication Service
10 | http://maven.apache.org
11 |
12 |
13 | org.springframework.boot
14 | spring-boot-starter-parent
15 | 1.5.7.RELEASE
16 |
17 |
18 |
19 | UTF-8
20 | 1.8
21 | 1.8
22 |
23 |
24 |
25 |
26 |
27 |
28 | org.springframework.boot
29 | spring-boot-starter-web
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter-security
34 |
35 |
36 | org.springframework.security.oauth
37 | spring-security-oauth2
38 |
39 |
40 | org.springframework.boot
41 | spring-boot-starter-data-jpa
42 |
43 |
44 |
45 |
46 | com.fasterxml.jackson.core
47 | jackson-databind
48 | 2.13.4.2
49 |
50 |
51 | com.fasterxml.jackson.core
52 | jackson-core
53 |
54 |
55 | com.fasterxml.jackson.core
56 | jackson-annotations
57 |
58 |
59 |
60 |
61 | com.fasterxml.jackson.core
62 | jackson-core
63 | 2.7.4
64 |
65 |
66 | com.fasterxml.jackson.core
67 | jackson-annotations
68 | 2.7.4
69 |
70 |
71 |
72 |
73 | org.springframework.security
74 | spring-security-jwt
75 | 1.0.8.RELEASE
76 |
77 |
78 |
79 | org.hibernate
80 | hibernate-core
81 | 5.4.24.Final
82 |
83 |
84 | org.hibernate
85 | hibernate-entitymanager
86 | 5.2.2.Final
87 |
88 |
89 |
90 | javassist
91 | javassist
92 | 3.3
93 |
94 |
95 |
96 |
97 | com.h2database
98 | h2
99 | runtime
100 |
101 |
102 |
103 |
104 | io.springfox
105 | springfox-swagger2
106 | 2.8.0
107 |
108 |
109 | io.springfox
110 | springfox-swagger-ui
111 | 2.8.0
112 |
113 |
114 | io.springfox
115 | springfox-bean-validators
116 | 2.8.0
117 |
118 |
119 | guava
120 | com.google.guava
121 | jar
122 | 18.0
123 |
124 |
125 |
126 |
127 | org.springframework.boot
128 | spring-boot-starter-test
129 | test
130 |
131 |
132 | org.mockito
133 | mockito-all
134 | 1.9.5
135 | test
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 | org.springframework.boot
145 | spring-boot-maven-plugin
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
--------------------------------------------------------------------------------
/authentication/src/main/java/com/authentication/Application.java:
--------------------------------------------------------------------------------
1 | package com.authentication;
2 |
3 |
4 | import org.springframework.boot.SpringApplication;
5 | import org.springframework.boot.autoconfigure.SpringBootApplication;
6 |
7 | /**
8 | * @author Rohit.Kumar
9 | */
10 | @SpringBootApplication
11 | public class Application {
12 |
13 | public static void main(String[] args) {
14 | SpringApplication.run(Application.class, args);
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/authentication/src/main/java/com/authentication/api/AuthenticationAPI.java:
--------------------------------------------------------------------------------
1 | package com.authentication.api;
2 |
3 | import com.authentication.model.UserTokenSession;
4 | import com.authentication.service.UserTokenSessionService;
5 | import com.authentication.service.UserTokenSessionServiceImpl;
6 | import io.swagger.annotations.*;
7 | import org.apache.log4j.Logger;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.beans.factory.annotation.Qualifier;
10 | import org.springframework.beans.factory.annotation.Value;
11 | import org.springframework.http.HttpHeaders;
12 | import org.springframework.http.HttpStatus;
13 | import org.springframework.http.MediaType;
14 | import org.springframework.http.ResponseEntity;
15 | import org.springframework.security.core.userdetails.UserDetailsService;
16 | import org.springframework.security.oauth2.provider.OAuth2Authentication;
17 | import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
18 | import org.springframework.web.bind.annotation.RequestHeader;
19 | import org.springframework.web.bind.annotation.RequestMapping;
20 | import org.springframework.web.bind.annotation.RequestMethod;
21 | import org.springframework.web.bind.annotation.RestController;
22 |
23 | import javax.servlet.http.HttpServletRequest;
24 | import java.security.Principal;
25 | import java.util.Objects;
26 |
27 | /**
28 | * @author Rohit.Kumar
29 | * @version 0.01
30 | */
31 | @RestController
32 | @RequestMapping("/oauth")
33 | @Api(value="Authentication API", description="Authenticate user using authorization token.")
34 | public class AuthenticationAPI {
35 |
36 | private static final Logger LOGGER = Logger.getLogger(AuthenticationAPI.class);
37 |
38 | @Autowired
39 | @Qualifier("userDetailsService")
40 | private UserDetailsService userDetailsService;
41 |
42 | @Value("${config.oauth2.tokenTimeout}")
43 | private long tokenExpiryTime;
44 |
45 | @Autowired
46 | private UserTokenSessionServiceImpl userTokenSessionService;
47 |
48 |
49 | @ApiOperation(value = "Authenticated User Login", response = UserTokenSession.class)
50 | @RequestMapping(value = "/login", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
51 | @ApiResponses(value = {
52 | @ApiResponse(code = 200, message = "Success", response = UserTokenSession.class),
53 | @ApiResponse(code = 401, message = "Unauthorized"),
54 | @ApiResponse(code = 403, message = "Forbidden"),
55 | @ApiResponse(code = 404, message = "Not Found"),
56 | @ApiResponse(code = 500, message = "Failure")})
57 | public ResponseEntity login(@RequestHeader HttpHeaders httpHeaders, Principal principal, HttpServletRequest httpServletRequest) {
58 |
59 | String username = principal.getName();
60 | UserTokenSession userTokenSession = buildUserTokenSession(principal, httpHeaders);
61 | userTokenSession = userTokenSessionService.saveUserTokenSessionMapping(userTokenSession);
62 |
63 | LOGGER.info("User "+username+" successfully logged in. User, Token and Session mapping stored."+userTokenSession);
64 |
65 | HttpHeaders responseHeaders = new HttpHeaders();
66 | responseHeaders.add("Message", "Success");
67 | responseHeaders.add("Set-Cookie", userTokenSession.getSessionId());
68 |
69 | return new ResponseEntity(userTokenSession, responseHeaders, HttpStatus.OK);
70 | }
71 |
72 | @ApiOperation(value = "Validate the given token", response = UserTokenSession.class)
73 | @RequestMapping(value = "/validateToken", method = RequestMethod.POST,
74 | produces = MediaType.APPLICATION_JSON_VALUE)
75 | @ApiResponses(value = {
76 | @ApiResponse(code = 200, message = "Success", response = UserTokenSession.class),
77 | @ApiResponse(code = 401, message = "Unauthorized"),
78 | @ApiResponse(code = 403, message = "Forbidden"),
79 | @ApiResponse(code = 404, message = "Not Found"),
80 | @ApiResponse(code = 500, message = "Failure")})
81 | public ResponseEntity validateToken(@RequestHeader HttpHeaders httpHeaders, Principal principal, HttpServletRequest httpServletRequest) {
82 |
83 |
84 | String username = principal.getName();
85 | UserTokenSession userTokenSession = buildUserTokenSession(principal, httpHeaders);
86 |
87 | ResponseEntity responseEntity;
88 | HttpHeaders responseHeaders = new HttpHeaders();
89 | responseHeaders.add("Set-Cookie", userTokenSession.getSessionId());
90 |
91 | UserTokenSessionService.ValidMappingResponse validMappingResponse = userTokenSessionService.isValidUserTokenSessionMapping(userTokenSession);
92 | if (validMappingResponse.isValid()) {
93 |
94 | LOGGER.info("User " + username + " has valid token."+validMappingResponse.getUserTokenSession());
95 | responseHeaders.add("Message", "Valid Token");
96 | responseEntity = new ResponseEntity(validMappingResponse.getUserTokenSession(), responseHeaders, HttpStatus.OK);
97 |
98 | } else {
99 |
100 | LOGGER.info("User " + username + " has invalid token.");
101 | responseHeaders.add("Message", "Invalid Token");
102 | responseEntity = new ResponseEntity(userTokenSession, responseHeaders, HttpStatus.UNAUTHORIZED);
103 | }
104 |
105 | return responseEntity;
106 | }
107 |
108 | /**
109 | * Build Token session using {@link Principal} and {@link HttpHeaders}
110 | * @param principal
111 | * @param httpHeaders
112 | * @return TokenSession
113 | */
114 | private UserTokenSession buildUserTokenSession(Principal principal, HttpHeaders httpHeaders) {
115 |
116 | OAuth2AuthenticationDetails oAuth2AuthenticationDetails = (OAuth2AuthenticationDetails) ((OAuth2Authentication) principal).getDetails();
117 | String tokenValue = oAuth2AuthenticationDetails.getTokenValue();
118 | String username = principal.getName();
119 | String [] sessionId = new String[1];
120 |
121 | if (Objects.nonNull(httpHeaders.get("cookie"))) {
122 | sessionId = httpHeaders.get("cookie").get(0).split(";");
123 | }else {
124 | LOGGER.info("User " + username + " cookie not found. JSessionId not set.");
125 |
126 | /**
127 | * Swagger2 does not support cookie for that putting default sessssion id.
128 | */
129 | sessionId[0] = "JSEESION-ID";
130 | }
131 |
132 | UserTokenSession userTokenSession = new UserTokenSession(username, tokenValue, sessionId[0], tokenExpiryTime);
133 | return userTokenSession;
134 | }
135 |
136 |
137 | }
138 |
--------------------------------------------------------------------------------
/authentication/src/main/java/com/authentication/config/AuthorizationServerConfig.java:
--------------------------------------------------------------------------------
1 | package com.authentication.config;
2 |
3 | import org.apache.log4j.Logger;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.beans.factory.annotation.Qualifier;
6 | import org.springframework.beans.factory.annotation.Value;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 | import org.springframework.context.annotation.Primary;
10 | import org.springframework.http.HttpMethod;
11 | import org.springframework.security.authentication.AuthenticationManager;
12 | import org.springframework.security.core.userdetails.UserDetailsService;
13 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
14 | import org.springframework.security.crypto.password.PasswordEncoder;
15 | import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
16 | import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
17 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
18 | import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
19 | import org.springframework.security.oauth2.provider.ClientDetailsService;
20 | import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
21 | import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
22 | import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
23 |
24 | /**
25 | * @author Rohit.Kumar
26 | */
27 | @Configuration
28 | @EnableAuthorizationServer
29 | public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
30 |
31 | private static final Logger LOGGER = Logger.getLogger(AuthorizationServerConfig.class);
32 |
33 | @Autowired
34 | @Qualifier("userDetailsService")
35 | private UserDetailsService userDetailsService;
36 |
37 | @Autowired
38 | private AuthenticationManager authenticationManager;
39 |
40 | @Value("${config.oauth2.tokenTimeout}")
41 | private int expiration;
42 |
43 | @Value("${config.oauth2.privateKey}")
44 | private String privateKey;
45 |
46 | @Value("${config.oauth2.publicKey}")
47 | private String publicKey;
48 |
49 | @Autowired
50 | private ClientDetailsService clientDetailsService;
51 |
52 | @Bean
53 | public PasswordEncoder passwordEncoder() {
54 | return new BCryptPasswordEncoder();
55 | }
56 |
57 |
58 | @Override
59 | public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
60 | clients
61 | .inMemory()
62 | .withClient("client")
63 | .authorizedGrantTypes("client_credentials", "password", "refresh_token", "authorization_code")
64 | .scopes("read", "write")
65 | .resourceIds("oauth2-resource")
66 | .accessTokenValiditySeconds(expiration)
67 | .refreshTokenValiditySeconds(expiration)
68 | .secret("secret");
69 |
70 | }
71 |
72 | @Bean
73 | public JwtAccessTokenConverter accessTokenConverter() {
74 |
75 | LOGGER.info("Initializing JWT with public key: " + publicKey);
76 |
77 | JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
78 | converter.setSigningKey(privateKey);
79 |
80 | return converter;
81 | }
82 |
83 | @Bean
84 | public JwtTokenStore tokenStore() {
85 | return new JwtTokenStore(accessTokenConverter());
86 | }
87 |
88 | @Bean
89 | @Primary
90 | public DefaultTokenServices tokenServices() {
91 | DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
92 | defaultTokenServices.setTokenStore(tokenStore());
93 | defaultTokenServices.setClientDetailsService(clientDetailsService);
94 | defaultTokenServices.setSupportRefreshToken(true);
95 | defaultTokenServices.setTokenEnhancer(accessTokenConverter());
96 | return defaultTokenServices;
97 | }
98 |
99 | /**
100 | * Defines the authorization and token endpoints and the token services
101 | * @param endpoints
102 | * @throws Exception
103 | */
104 | @Override
105 | public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
106 |
107 | endpoints
108 | .authenticationManager(authenticationManager)
109 | .userDetailsService(userDetailsService)
110 | .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
111 | .tokenStore(tokenStore())
112 | .tokenServices(tokenServices())
113 | .accessTokenConverter(accessTokenConverter());
114 | }
115 |
116 |
117 |
118 | }
119 |
--------------------------------------------------------------------------------
/authentication/src/main/java/com/authentication/config/PersistentContext.java:
--------------------------------------------------------------------------------
1 | package com.authentication.config;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.ComponentScan;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
7 | import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
8 | import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
9 | import org.springframework.orm.jpa.JpaTransactionManager;
10 | import org.springframework.orm.jpa.JpaVendorAdapter;
11 | import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
12 | import org.springframework.orm.jpa.vendor.Database;
13 | import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
14 |
15 | import javax.persistence.EntityManagerFactory;
16 | import javax.sql.DataSource;
17 |
18 | /**
19 | * @author Rohit.Kumar
20 | */
21 | @Configuration
22 | @ComponentScan("com.authentication")
23 | @EnableJpaRepositories("com.authentication.repository")
24 | public class PersistentContext {
25 |
26 | @Bean
27 | public DataSource dataSource() {
28 | return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build();
29 | }
30 |
31 | @Bean
32 | public JpaVendorAdapter jpaVendorAdapter() {
33 | HibernateJpaVendorAdapter bean = new HibernateJpaVendorAdapter();
34 | bean.setDatabase(Database.H2);
35 | bean.setGenerateDdl(true);
36 | return bean;
37 | }
38 |
39 | @Bean
40 | public LocalContainerEntityManagerFactoryBean entityManagerFactory(
41 | DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
42 |
43 | LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean();
44 | bean.setDataSource(dataSource);
45 | bean.setJpaVendorAdapter(jpaVendorAdapter);
46 | bean.setPackagesToScan("com.authentication");
47 | return bean;
48 | }
49 |
50 | @Bean
51 | public JpaTransactionManager transactionManager(EntityManagerFactory emf) {
52 | return new JpaTransactionManager(emf);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/authentication/src/main/java/com/authentication/config/ResourceServerConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.authentication.config;
2 |
3 | import org.apache.log4j.Logger;
4 | import org.springframework.beans.factory.annotation.Value;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.context.annotation.Primary;
8 | import org.springframework.http.HttpMethod;
9 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
10 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
11 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
12 | import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
13 | import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
14 | import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
15 | import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
16 |
17 | /**
18 | * @author Rohit.Kumar
19 | */
20 | @Configuration
21 | @EnableResourceServer
22 | public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
23 |
24 | private static final Logger LOGGER = Logger.getLogger(ResourceServerConfiguration.class);
25 |
26 |
27 | @Value("${config.oauth2.publicKey}")
28 | private String publicKey;
29 |
30 | @Value("${config.oauth2.privateKey}")
31 | private String privateKey;
32 |
33 | @Value("${config.oauth2.resource.id}")
34 | private String resourceId;
35 |
36 |
37 | @Override
38 | public void configure(HttpSecurity http) throws Exception {
39 | http
40 | .csrf().disable()
41 | .anonymous().disable()
42 | .authorizeRequests()
43 | .antMatchers(HttpMethod.OPTIONS).permitAll()
44 | .antMatchers("/oauth/**").authenticated();
45 |
46 | }
47 |
48 |
49 | @Override
50 | public void configure(ResourceServerSecurityConfigurer resources) {
51 | resources
52 | .resourceId(resourceId)
53 | .tokenServices(tokenServices())
54 | .tokenStore(tokenStore());
55 | }
56 |
57 | @Bean
58 | @Primary
59 | public DefaultTokenServices tokenServices() {
60 | DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
61 | defaultTokenServices.setTokenStore(tokenStore());
62 | defaultTokenServices.setSupportRefreshToken(true);
63 | defaultTokenServices.setTokenEnhancer(accessTokenConverter());
64 | return defaultTokenServices;
65 | }
66 |
67 | @Bean
68 | public JwtAccessTokenConverter accessTokenConverter() {
69 |
70 | LOGGER.info("Initializing JWT with public key: " + publicKey);
71 |
72 | JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
73 | converter.setSigningKey(privateKey);
74 |
75 | return converter;
76 | }
77 |
78 | @Bean
79 | public JwtTokenStore tokenStore() {
80 | return new JwtTokenStore(accessTokenConverter());
81 | }
82 |
83 |
84 | }
--------------------------------------------------------------------------------
/authentication/src/main/java/com/authentication/config/SwaggerConfig.java:
--------------------------------------------------------------------------------
1 | package com.authentication.config;
2 |
3 | import org.springframework.beans.factory.annotation.Value;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.ComponentScan;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.http.HttpHeaders;
8 | import springfox.documentation.builders.ApiInfoBuilder;
9 | import springfox.documentation.builders.PathSelectors;
10 | import springfox.documentation.builders.RequestHandlerSelectors;
11 | import springfox.documentation.service.*;
12 | import springfox.documentation.spi.DocumentationType;
13 | import springfox.documentation.spi.service.contexts.SecurityContext;
14 | import springfox.documentation.spring.web.plugins.Docket;
15 | import springfox.documentation.swagger.web.ApiKeyVehicle;
16 | import springfox.documentation.swagger.web.SecurityConfiguration;
17 | import springfox.documentation.swagger2.annotations.EnableSwagger2;
18 |
19 | import java.util.Arrays;
20 | import java.util.Collections;
21 | import java.util.List;
22 |
23 | import static org.hibernate.validator.internal.util.CollectionHelper.newArrayList;
24 |
25 | /**
26 | * TODO Swagger UI to be completed, as of now there are some issues in authentication.
27 | * @author Rohit.Kumar
28 | */
29 | @Configuration
30 | @EnableSwagger2
31 | @ComponentScan(basePackages = "com.authentication.api")
32 | public class SwaggerConfig {
33 |
34 |
35 | @Value("${config.oauth2.accessTokenUri}")
36 | private String accessTokenUri;
37 |
38 |
39 | public static final String securitySchemaOAuth2 = "oauth2schema";
40 | public static final String authorizationScopeGlobal = "global";
41 | public static final String authorizationScopeGlobalDesc ="accessEverything";
42 | /**
43 | *
44 | * @return Docket
45 | */
46 | @Bean
47 | public Docket productApi() {
48 |
49 |
50 | return new Docket(DocumentationType.SWAGGER_2)
51 | .select()
52 | .apis(RequestHandlerSelectors.any())
53 | .paths(PathSelectors.any())
54 | .build()
55 | .securityContexts(Collections.singletonList(securityContext()))
56 | .securitySchemes(Arrays.asList(securitySchema(), apiKey(), apiCookieKey()))
57 | .apiInfo(apiInfo());
58 |
59 |
60 | }
61 |
62 | @Bean
63 | public SecurityScheme apiKey() {
64 | return new ApiKey(HttpHeaders.AUTHORIZATION, "apiKey", "header");
65 | }
66 |
67 | @Bean
68 | public SecurityScheme apiCookieKey() {
69 | return new ApiKey(HttpHeaders.COOKIE, "apiKey", "cookie");
70 | }
71 |
72 | private OAuth securitySchema() {
73 |
74 | List authorizationScopeList = newArrayList();
75 | authorizationScopeList.add(new AuthorizationScope("read", "read all"));
76 | authorizationScopeList.add(new AuthorizationScope("write", "access all"));
77 |
78 | List grantTypes = newArrayList();
79 | GrantType passwordCredentialsGrant = new ResourceOwnerPasswordCredentialsGrant(accessTokenUri);
80 | grantTypes.add(passwordCredentialsGrant);
81 |
82 | return new OAuth("oauth2", authorizationScopeList, grantTypes);
83 | }
84 |
85 | private SecurityContext securityContext() {
86 | return SecurityContext.builder().securityReferences(defaultAuth())
87 | .build();
88 | }
89 |
90 |
91 |
92 | private List defaultAuth() {
93 |
94 | final AuthorizationScope[] authorizationScopes = new AuthorizationScope[3];
95 | authorizationScopes[0] = new AuthorizationScope("read", "read all");
96 | authorizationScopes[1] = new AuthorizationScope("trust", "trust all");
97 | authorizationScopes[2] = new AuthorizationScope("write", "write all");
98 |
99 | return Collections.singletonList(new SecurityReference("oauth2", authorizationScopes));
100 | }
101 |
102 | @Bean
103 | public SecurityConfiguration security() {
104 | return new SecurityConfiguration
105 | ("client", "secret", "", "", "Bearer access token", ApiKeyVehicle.HEADER, HttpHeaders.AUTHORIZATION,"");
106 | }
107 |
108 |
109 | /**
110 | *
111 | * @return ApiInf
112 | */
113 | private ApiInfo apiInfo() {
114 | return new ApiInfoBuilder().title("Authentication API").description("")
115 | .termsOfServiceUrl("https://www.example.com/api")
116 | .contact(new Contact("Developers", "https://projects.spring.io/spring-boot/", ""))
117 | .license("Open Source")
118 | .licenseUrl("\"https://www.apache.org/licenses/LICENSE-2.0")
119 | .version("1.0.0")
120 | .build();
121 |
122 | }
123 |
124 | }
125 |
--------------------------------------------------------------------------------
/authentication/src/main/java/com/authentication/config/WebSecurityConfig.java:
--------------------------------------------------------------------------------
1 | package com.authentication.config;
2 |
3 | import org.springframework.boot.autoconfigure.security.SecurityProperties;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.core.annotation.Order;
7 | import org.springframework.security.authentication.AuthenticationManager;
8 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
9 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
10 |
11 |
12 | /**
13 | * @author Rohit.Kumar
14 | */
15 | @Configuration
16 | @EnableWebSecurity(debug = true)
17 | @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
18 | public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
19 |
20 |
21 | @Bean
22 | @Override
23 | public AuthenticationManager authenticationManagerBean() throws Exception {
24 | return super.authenticationManagerBean();
25 | }
26 |
27 |
28 | }
--------------------------------------------------------------------------------
/authentication/src/main/java/com/authentication/config/package-info.java:
--------------------------------------------------------------------------------
1 | package com.authentication.config;
2 | /*
3 | This Package contains all configuration classed related security micro-service.
4 | */
--------------------------------------------------------------------------------
/authentication/src/main/java/com/authentication/model/User.java:
--------------------------------------------------------------------------------
1 | package com.authentication.model;
2 |
3 | import io.swagger.annotations.ApiModelProperty;
4 | import org.springframework.security.core.GrantedAuthority;
5 | import org.springframework.security.core.userdetails.UserDetails;
6 |
7 | import javax.persistence.*;
8 | import java.time.LocalDateTime;
9 | import java.util.ArrayList;
10 | import java.util.Collection;
11 | import java.util.List;
12 |
13 |
14 | /**
15 | * @author Rohit.Kumar
16 | */
17 | @Entity
18 | @Table(name = "users")
19 | public class User implements UserDetails {
20 |
21 | static final long serialVersionUID = 1L;
22 |
23 | @Id
24 | @GeneratedValue(strategy = GenerationType.AUTO)
25 | @Column(name = "user_id", nullable = false, updatable = false)
26 | @ApiModelProperty(notes = "The database generated user, token and session mapping ID.")
27 | private Long id;
28 |
29 | @Column(name = "username", nullable = false, unique = true)
30 | @ApiModelProperty(notes = "user name")
31 | private String username;
32 |
33 | @Column(name = "password", nullable = false)
34 | @ApiModelProperty(notes = "User password")
35 | private String password;
36 |
37 | @Column(name = "enabled", nullable = false)
38 | @ApiModelProperty(notes = "Indicates whether the user is enabled or disabled. A disabled user cannot be authenticated.")
39 | private boolean enabled;
40 |
41 | @Column(name = "created_time", insertable=true, updatable=false)
42 | @ApiModelProperty(notes = "The database generated user, token and session mapping created time.")
43 | private LocalDateTime createdTime;
44 |
45 | @Column(name = "updated_time", insertable=false, updatable=true)
46 | @ApiModelProperty(notes = "The database generated user, token and session mapping updated time.")
47 | private LocalDateTime updatedTime;
48 |
49 | @PrePersist
50 | protected void onCreate() {
51 | createdTime = LocalDateTime.now();
52 | updatedTime = LocalDateTime.now();
53 | }
54 |
55 | @PreUpdate
56 | protected void onUpdate() {
57 | updatedTime = LocalDateTime.now();
58 | }
59 |
60 |
61 | @Override
62 | public Collection extends GrantedAuthority> getAuthorities() {
63 | List authorities = new ArrayList();
64 |
65 | return authorities;
66 | }
67 |
68 | @Override
69 | public boolean isAccountNonExpired() {
70 | return true;
71 | }
72 |
73 | @Override
74 | public boolean isAccountNonLocked() {
75 | return true;
76 | }
77 |
78 | @Override
79 | public boolean isCredentialsNonExpired() {
80 | return true;
81 | }
82 |
83 | @Override
84 | public boolean isEnabled() {
85 | return enabled;
86 | }
87 |
88 | @Override
89 | public String getPassword() {
90 | return password;
91 | }
92 |
93 | @Override
94 | public String getUsername() {
95 | return username;
96 | }
97 |
98 | public Long getId() {
99 | return id;
100 | }
101 |
102 | public LocalDateTime getCreatedTime() {
103 | return createdTime;
104 | }
105 |
106 | public LocalDateTime getUpdatedTime() {
107 | return updatedTime;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/authentication/src/main/java/com/authentication/model/UserTokenSession.java:
--------------------------------------------------------------------------------
1 | package com.authentication.model;
2 |
3 |
4 | import io.swagger.annotations.ApiModelProperty;
5 |
6 | import javax.persistence.*;
7 | import java.time.LocalDateTime;
8 | import java.util.Objects;
9 |
10 |
11 | /**
12 | * @author Rohit.Kumar
13 | */
14 | @Entity
15 | @Table(name = "tbl_user_token_session")
16 | public class UserTokenSession {
17 |
18 | static final long serialVersionUID = 1L;
19 |
20 | @Id
21 | @GeneratedValue(strategy = GenerationType.AUTO)
22 | @Column(name = "id", nullable = false, updatable = false)
23 | @ApiModelProperty(notes = "The database generated user, token and session mapping ID.")
24 | private Long id;
25 |
26 | @Column(name = "username", nullable = false, unique = true)
27 | @ApiModelProperty(notes = "user name.")
28 | private String username;
29 |
30 | @Column(name = "token", nullable = false, unique = true, length = 500)
31 | @ApiModelProperty(notes = "Authorization token.")
32 | private String token;
33 |
34 | @Column(name = "session_id", nullable = false, unique = true)
35 | @ApiModelProperty(notes = "Session-id received in request header.")
36 | private String sessionId;
37 |
38 | @Column(name = "expiry_time", nullable = false)
39 | @ApiModelProperty(notes = "Authorization token expiry time.")
40 | private Long expiryTime;
41 |
42 | @Column(name = "created_time", insertable=true, updatable=false)
43 | @ApiModelProperty(notes = "The database generated user, token and session mapping created time.")
44 | private LocalDateTime createdTime;
45 |
46 | @Column(name = "updated_time", insertable=false, updatable=true)
47 | @ApiModelProperty(notes = "The database generated user, token and session mapping updated time.")
48 | private LocalDateTime updatedTime;
49 |
50 | @PrePersist
51 | protected void onCreate() {
52 | createdTime = LocalDateTime.now();
53 | updatedTime = LocalDateTime.now();
54 | }
55 |
56 | @PreUpdate
57 | protected void onUpdate() {
58 | updatedTime = LocalDateTime.now();
59 | }
60 |
61 | public UserTokenSession() {
62 | }
63 |
64 | public UserTokenSession(String username, String token, String sessionId, Long expiryTime) {
65 | this.username = username;
66 | this.token = token;
67 | this.sessionId = sessionId;
68 | this.expiryTime = expiryTime;
69 | }
70 |
71 | public Long getId() {
72 | return id;
73 | }
74 |
75 | public String getUsername() {
76 | return username;
77 | }
78 |
79 | public String getToken() {
80 | return token;
81 | }
82 |
83 | public String getSessionId() {
84 | return sessionId;
85 | }
86 |
87 | public Long getExpiryTime() {
88 | return expiryTime;
89 | }
90 |
91 | public LocalDateTime getCreatedTime() {
92 | return createdTime;
93 | }
94 |
95 | public LocalDateTime getUpdatedTime() {
96 | return updatedTime;
97 | }
98 |
99 | @Override
100 | public boolean equals(Object o) {
101 | if (this == o) return true;
102 | if (o == null || getClass() != o.getClass()) return false;
103 | UserTokenSession that = (UserTokenSession) o;
104 | return Objects.equals(username, that.username) &&
105 | Objects.equals(token, that.token) &&
106 | Objects.equals(sessionId, that.sessionId) &&
107 | Objects.equals(expiryTime, that.expiryTime);
108 | }
109 |
110 | @Override
111 | public int hashCode() {
112 |
113 | return Objects.hash(username, token, sessionId, expiryTime);
114 | }
115 |
116 | @Override
117 | public String toString() {
118 | return "UserTokenSession{" +
119 | "id=" + id +
120 | ", username='" + username + '\'' +
121 | ", token='" + token + '\'' +
122 | ", sessionId='" + sessionId + '\'' +
123 | ", expiryTime=" + expiryTime +
124 | ", createdTime=" + createdTime +
125 | ", updatedTime=" + updatedTime +
126 | '}';
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/authentication/src/main/java/com/authentication/repository/UserRepository.java:
--------------------------------------------------------------------------------
1 | package com.authentication.repository;
2 |
3 | import com.authentication.model.User;
4 | import org.springframework.data.jpa.repository.JpaRepository;
5 | import org.springframework.stereotype.Repository;
6 |
7 | /**
8 | * @author Rohit.Kumar
9 | */
10 | @Repository
11 | public interface UserRepository extends JpaRepository {
12 |
13 | /**
14 | *
15 | * @param username
16 | * @return @{@link User}
17 | */
18 | User findOneByUsername(String username);
19 | }
20 |
--------------------------------------------------------------------------------
/authentication/src/main/java/com/authentication/repository/UserTokenSessionRepository.java:
--------------------------------------------------------------------------------
1 | package com.authentication.repository;
2 |
3 | import com.authentication.model.UserTokenSession;
4 | import org.springframework.data.repository.CrudRepository;
5 | import org.springframework.stereotype.Repository;
6 |
7 | /**
8 | * @author Rohit.Kumar
9 | */
10 | @Repository
11 | public interface UserTokenSessionRepository extends CrudRepository {
12 |
13 | /**
14 | * Find {@link UserTokenSession} for the given username.
15 | * @param username
16 | * @return @{@link UserTokenSession}
17 | */
18 | UserTokenSession findOneByUsername(String username);
19 |
20 | }
--------------------------------------------------------------------------------
/authentication/src/main/java/com/authentication/service/UserDetailsServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.authentication.service;
2 |
3 | import com.authentication.model.User;
4 | import com.authentication.repository.UserRepository;
5 | import org.apache.log4j.Logger;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.security.core.userdetails.UserDetails;
8 | import org.springframework.security.core.userdetails.UserDetailsService;
9 | import org.springframework.security.core.userdetails.UsernameNotFoundException;
10 | import org.springframework.stereotype.Service;
11 |
12 | /**
13 | * @author Rohit.Kumar
14 | */
15 | @Service("userDetailsService")
16 | public class UserDetailsServiceImpl implements UserDetailsService {
17 |
18 | private static final Logger LOGGER = Logger.getLogger(UserDetailsServiceImpl.class);
19 |
20 | @Autowired
21 | private UserRepository userRepository;
22 |
23 | @Override
24 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
25 |
26 | User userFromDataBase = userRepository.findOneByUsername(username);
27 | if (userFromDataBase == null) {
28 | LOGGER.info("User " + username + " was not found in the database");
29 | throw new UsernameNotFoundException("User " + username + " was not found in the database");
30 | }
31 | return userFromDataBase;
32 |
33 | }
34 | }
--------------------------------------------------------------------------------
/authentication/src/main/java/com/authentication/service/UserTokenSessionService.java:
--------------------------------------------------------------------------------
1 | package com.authentication.service;
2 |
3 | import com.authentication.model.UserTokenSession;
4 | import org.springframework.security.core.userdetails.UsernameNotFoundException;
5 |
6 | /**
7 | * @author Rohit.Kumar
8 | */
9 | public interface UserTokenSessionService {
10 |
11 | /**
12 | * Check whether there is mapping between oauth token, username and session-id.
13 | * And the token is not yet expired.
14 | * @param userTokenSession
15 | * @return ValidMappingResponse if valid mapping else throw {@link UsernameNotFoundException}
16 | */
17 | ValidMappingResponse isValidUserTokenSessionMapping(UserTokenSession userTokenSession) throws UsernameNotFoundException;
18 |
19 | /**
20 | *
21 | * @param userTokenSession
22 | * @return token session record from data base.
23 | */
24 | UserTokenSession saveUserTokenSessionMapping(UserTokenSession userTokenSession);
25 |
26 |
27 | /**
28 | * Class to store isValidUserTokenSessionMapping() response.
29 | */
30 | class ValidMappingResponse {
31 |
32 | private boolean valid;
33 | private UserTokenSession userTokenSession;
34 |
35 | public ValidMappingResponse() {
36 | }
37 |
38 | public ValidMappingResponse(boolean valid, UserTokenSession userTokenSession ) {
39 | this.valid = valid;
40 | this.userTokenSession = userTokenSession;
41 | }
42 |
43 | public boolean isValid() {
44 | return valid;
45 | }
46 |
47 | public void setValid(boolean valid) {
48 | this.valid = valid;
49 | }
50 |
51 | public UserTokenSession getUserTokenSession() {
52 | return userTokenSession;
53 | }
54 |
55 | public void setUserTokenSession(UserTokenSession userTokenSession) {
56 | this.userTokenSession = userTokenSession;
57 | }
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/authentication/src/main/java/com/authentication/service/UserTokenSessionServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.authentication.service;
2 |
3 | import com.authentication.model.UserTokenSession;
4 | import com.authentication.repository.UserTokenSessionRepository;
5 | import org.apache.log4j.Logger;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.security.core.userdetails.UsernameNotFoundException;
8 | import org.springframework.stereotype.Service;
9 |
10 | import java.time.LocalDateTime;
11 | import java.time.ZoneId;
12 | import java.time.ZonedDateTime;
13 | import java.util.Objects;
14 |
15 | /**
16 | * @author Rohit.Kumar
17 | */
18 | @Service
19 | public class UserTokenSessionServiceImpl implements UserTokenSessionService {
20 |
21 | private static final Logger LOGGER = Logger.getLogger(UserTokenSessionServiceImpl.class);
22 |
23 | @Autowired
24 | private UserTokenSessionRepository userTokenSessionRepository;
25 |
26 |
27 | @Override
28 | public ValidMappingResponse isValidUserTokenSessionMapping(UserTokenSession userTokenSession) throws UsernameNotFoundException {
29 |
30 | String username = userTokenSession.getUsername();
31 | UserTokenSession userTokenSessionFromDB = userTokenSessionRepository.findOneByUsername(username);
32 |
33 | if (Objects.isNull(userTokenSessionFromDB)) {
34 |
35 | LOGGER.error("User " + username + " mapping with token is not found in the database.");
36 | throw new UsernameNotFoundException("User " + username + " mapping with token is not found in the database.");
37 | }
38 |
39 | /**
40 | * TODO Time zone of data base and client may be different.
41 | */
42 | LocalDateTime currentSystemTime = LocalDateTime.now();
43 | ZonedDateTime currentZonedDateTime = currentSystemTime.atZone(ZoneId.systemDefault());
44 | long currentTimeInMillis = currentZonedDateTime.toInstant().toEpochMilli();
45 |
46 | ZonedDateTime dataBaseZonedDateTime = userTokenSessionFromDB.getCreatedTime().atZone(ZoneId.systemDefault());
47 |
48 | /**
49 | * tokenTimeInMillis = created_time in millis + expiry time (seconds) * 1000.
50 | */
51 | long tokenTimeInMillis = dataBaseZonedDateTime.toInstant().toEpochMilli() + (userTokenSessionFromDB.getExpiryTime() * 1000);
52 |
53 | if ( currentTimeInMillis >= tokenTimeInMillis) {
54 |
55 | LOGGER.info("User " + username + " token has expired. Please generate new token. Deleting the expired token mapping.");
56 | userTokenSessionRepository.delete(userTokenSessionFromDB);
57 | throw new UsernameNotFoundException("User " + username + " token has expired. Please generate new token.");
58 |
59 | }else if(!userTokenSession.equals(userTokenSessionFromDB)) {
60 |
61 | if (!userTokenSessionFromDB.getToken().equals(userTokenSession.getToken())){
62 | LOGGER.info("User "+userTokenSession.getUsername()+ " has invalid user and token mapping. Please generate new token.");
63 |
64 | } else {
65 | LOGGER.info("User "+userTokenSession.getUsername()+ " has invalid user and session-id mapping. Please generate new token.");
66 | }
67 |
68 | LOGGER.info("So, Deleting the invalid mapping.");
69 | userTokenSessionRepository.delete(userTokenSessionFromDB);
70 | throw new UsernameNotFoundException("User " + username + " has invalid user, session-id and token mapping. Please generate new token.");
71 |
72 | }else {
73 |
74 | LOGGER.info("User " + username + " has valid token.");
75 | ValidMappingResponse validMappingResponse = new ValidMappingResponse(true, userTokenSessionFromDB);
76 | return validMappingResponse;
77 | }
78 |
79 | }
80 |
81 | @Override
82 | public UserTokenSession saveUserTokenSessionMapping(UserTokenSession userTokenSession) {
83 |
84 | UserTokenSession userTokenSessionFromDB = userTokenSessionRepository.findOneByUsername(userTokenSession.getUsername());
85 |
86 | /**
87 | * 1. If User is making the login call again with the same session-id and token. Then delete the old mapping and return the new inserted mapping.
88 | * 2. If same user is making login call with the new token or session-id. Then delete the old mapping and return the new inserted mapping
89 | */
90 | if (Objects.nonNull(userTokenSessionFromDB)) {
91 |
92 | if (userTokenSessionFromDB.equals(userTokenSession)) {
93 | LOGGER.info("User "+userTokenSession.getUsername()+ " making login call again with same token and session-id.");
94 |
95 | } else if (!userTokenSessionFromDB.getToken().equals(userTokenSession.getToken())){
96 | LOGGER.info("User "+userTokenSession.getUsername()+ " making login call with new token");
97 |
98 | } else {
99 | LOGGER.info("User "+userTokenSession.getUsername()+ " making login call with different session-id");
100 |
101 | }
102 | LOGGER.info("So, Deleting older mapping from tbl_user_token_session."+userTokenSessionFromDB);
103 | userTokenSessionRepository.delete(userTokenSessionFromDB);
104 |
105 | }
106 |
107 | return userTokenSessionRepository.save(userTokenSession);
108 | }
109 |
110 |
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/authentication/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | server.port=8080
2 | server.contextPath=/api
3 |
4 | logging.level.com.alfred=DEBUG
5 |
6 | # Data source properties
7 | spring.jpa.hibernate.ddl-auto=validate
8 | spring.jpa.show-sql=true
9 |
10 | # openssl genrsa -out jwt.pem 2048
11 | # openssl rsa -in jwt.pem
12 | config.oauth2.privateKey=MIICXQIBAAKBgQDNQZKqTlO/+2b4ZdhqGJzGBDltb5PZmBz1ALN2YLvt341pH6i5mO1V9cX5Ty1LM70fKfnIoYUP4KCE33dPnC7LkUwE/myh1zM6m8cbL5cYFPyP099thbVxzJkjHWqywvQih/qOOjliomKbM9pxG8Z1dB26hL9dSAZuA8xExjlPmQIDAQABAoGAImnYGU3ApPOVtBf/TOqLfne+2SZX96eVU06myDY3zA4rO3DfbR7CzCLE6qPnyDAIiW0UQBs0oBDdWOnOqz5YaePZu/yrLyj6KM6Q2e9ywRDtDh3ywrSfGpjdSvvoaeL1WesBWsgWv1vFKKvES7ILFLUxKwyCRC2Lgh7aI9GGZfECQQD84m98Yrehhin3fZuRaBNIu348Ci7ZFZmrvyxAIxrV4jBjpACW0RM2BvF5oYM2gOJqIfBOVjmPwUrobYEFcHRvAkEAz8jsfmxsZVwh3Y/Y47BzhKIC5FLaads541jNjVWfrPirljyCy1n4sg3WQH2IEyap3WTP84+csCtsfNfyK7fQdwJBAJNRyobY74cupJYkW5OK4OkXKQQLHp2iosJV/Y5jpQeC3JO/gARcSmfIBbbI66q9zKjtmpPYUXI4tc3PtUEY8QsCQQCcxySyC0sKe6bNzyC+Q8AVvkxiTKWiI5idEr8duhJd589H72Zc2wkMB+a2CEGo+Y5Hjy5cvuph/pG/7Qw7sljnAkAy/feClt1mUEiAcWrHRwcQ71AoA0+21yC9VkqPNrn3w7OEg8gBqPjRlXBNb00QieNeGGSkXOoU6gFschR22Dzy
13 |
14 | # openssl rsa -in jwt.pem -pubout
15 | config.oauth2.publicKey=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNQZKqTlO/+2b4ZdhqGJzGBDltb5PZmBz1ALN2YLvt341pH6i5mO1V9cX5Ty1LM70fKfnIoYUP4KCE33dPnC7LkUwE/myh1zM6m8cbL5cYFPyP099thbVxzJkjHWqywvQih/qOOjliomKbM9pxG8Z1dB26hL9dSAZuA8xExjlPmQIDAQAB
16 |
17 |
18 | #oauth configurations
19 | config.oauth2.tokenTimeout=3600
20 | config.oauth2.resource.id=oauth2-resource
21 | config.oauth2.clientID=client
22 | config.oauth2.clientSecret=secret
23 | security.oauth2.client.grantType=client_credentials
24 | config.oauth2.accessTokenUri=http://localhost:8080/api/oauth/token
25 | config.oauth2.userAuthorizationUri=http://localhost:8080/api/oauth/authorize
26 | config.oauth2.resourceURI= http://localhost:8080/api/oauth/authorize
27 |
--------------------------------------------------------------------------------
/authentication/src/main/resources/data.sql:
--------------------------------------------------------------------------------
1 | INSERT INTO users (user_id, username, password, enabled) VALUES
2 | ('1', 'user1@example.com', '$2a$10$D4OLKI6yy68crm.3imC9X.P2xqKHs5TloWUcr6z5XdOqnTrAK84ri', true),
3 | ('2', 'user2@example.com', '$2a$10$D4OLKI6yy68crm.3imC9X.P2xqKHs5TloWUcr6z5XdOqnTrAK84ri', true),
4 | ('3', 'user3@example.com', '$2a$10$D4OLKI6yy68crm.3imC9X.P2xqKHs5TloWUcr6z5XdOqnTrAK84ri', true);
5 |
6 |
--------------------------------------------------------------------------------
/authentication/src/main/resources/images/Swagger-UI-Home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rrohitramsen/spring-boot-oauth2-jwt-swagger-ui/97fa9a3063bf4367aa572a5c102295104ee9208e/authentication/src/main/resources/images/Swagger-UI-Home.png
--------------------------------------------------------------------------------
/authentication/src/main/resources/images/Swagger-ui-auth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rrohitramsen/spring-boot-oauth2-jwt-swagger-ui/97fa9a3063bf4367aa572a5c102295104ee9208e/authentication/src/main/resources/images/Swagger-ui-auth.png
--------------------------------------------------------------------------------
/authentication/src/main/resources/images/swagger-ui-login-token.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rrohitramsen/spring-boot-oauth2-jwt-swagger-ui/97fa9a3063bf4367aa572a5c102295104ee9208e/authentication/src/main/resources/images/swagger-ui-login-token.png
--------------------------------------------------------------------------------
/authentication/src/main/resources/images/swagger-ui-login.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rrohitramsen/spring-boot-oauth2-jwt-swagger-ui/97fa9a3063bf4367aa572a5c102295104ee9208e/authentication/src/main/resources/images/swagger-ui-login.png
--------------------------------------------------------------------------------
/authentication/src/main/resources/schema.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE IF EXISTS users;
2 | CREATE TABLE users (
3 | user_id BIGINT PRIMARY KEY auto_increment,
4 | username VARCHAR(128) UNIQUE,
5 | password VARCHAR(256),
6 | enabled BOOL
7 | );
8 |
9 |
--------------------------------------------------------------------------------
/authentication/src/test/java/com/authentication/api/AuthenticationAPITest.java:
--------------------------------------------------------------------------------
1 | package com.authentication.api;
2 |
3 | import com.authentication.model.UserTokenSession;
4 | import com.authentication.service.UserDetailsServiceImpl;
5 | import com.authentication.service.UserTokenSessionService;
6 | import com.authentication.service.UserTokenSessionServiceImpl;
7 | import org.junit.Before;
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 | import org.mockito.InjectMocks;
11 | import org.mockito.Mockito;
12 | import org.mockito.MockitoAnnotations;
13 | import org.springframework.beans.factory.annotation.Autowired;
14 | import org.springframework.beans.factory.annotation.Value;
15 | import org.springframework.boot.test.context.SpringBootTest;
16 | import org.springframework.http.HttpHeaders;
17 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
18 | import org.springframework.security.core.Authentication;
19 | import org.springframework.security.core.userdetails.UserDetailsService;
20 | import org.springframework.security.oauth2.provider.OAuth2Authentication;
21 | import org.springframework.security.oauth2.provider.OAuth2Request;
22 | import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
23 | import org.springframework.test.context.junit4.SpringRunner;
24 | import org.springframework.test.context.web.WebAppConfiguration;
25 | import org.springframework.test.web.servlet.MockMvc;
26 | import org.springframework.test.web.servlet.request.RequestPostProcessor;
27 | import org.springframework.test.web.servlet.setup.MockMvcBuilders;
28 | import org.springframework.util.ReflectionUtils;
29 |
30 | import javax.servlet.http.HttpServletRequest;
31 | import java.io.IOException;
32 | import java.lang.reflect.Field;
33 |
34 | import static org.mockito.Matchers.any;
35 |
36 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
37 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
38 |
39 | /**
40 | * @implNote This class provide Junits for {@link AuthenticationAPI} class.
41 | * @author Rohit.Kumar
42 | *
43 | */
44 | @RunWith(SpringRunner.class)
45 | @WebAppConfiguration
46 | @SpringBootTest
47 | public class AuthenticationAPITest {
48 |
49 | @InjectMocks
50 | private AuthenticationAPI authenticationAPI;
51 |
52 | private MockMvc mockMvc;
53 | private UserDetailsService userDetailsService;
54 | private UserTokenSessionServiceImpl userTokenSessionService;
55 |
56 | @Value("${config.oauth2.tokenTimeout}")
57 | private String tokenExpiryTime;
58 |
59 |
60 | @Autowired
61 | private OAuthHelper oAuthHelper;
62 |
63 | private RequestPostProcessor requestPostProcessor;
64 | private UserTokenSession userTokenSession;
65 | private HttpHeaders httpHeaders;
66 | private OAuth2Authentication oAuth2Authentication;
67 |
68 | @Before
69 | public void setup() throws IOException {
70 |
71 | MockitoAnnotations.initMocks(this);
72 | userDetailsService = Mockito.mock(UserDetailsServiceImpl.class);
73 | userTokenSessionService = Mockito.mock(UserTokenSessionServiceImpl.class);
74 | Field field = ReflectionUtils.findField(AuthenticationAPI.class, "userDetailsService");
75 | ReflectionUtils.makeAccessible(field);
76 | ReflectionUtils.setField(field, authenticationAPI, userDetailsService);
77 |
78 | field = ReflectionUtils.findField(AuthenticationAPI.class, "userTokenSessionService");
79 | ReflectionUtils.makeAccessible(field);
80 | ReflectionUtils.setField(field, authenticationAPI, userTokenSessionService);
81 |
82 | this.mockMvc = MockMvcBuilders.standaloneSetup(authenticationAPI).build();
83 |
84 |
85 | /**
86 | * testLogin and testValidateToken Set-up
87 | */
88 |
89 | String username = "user";
90 | String password = "password";
91 |
92 | requestPostProcessor = oAuthHelper.addBearerToken(username, password);
93 | Authentication authentication = new UsernamePasswordAuthenticationToken(username, password);
94 | OAuth2Request oAuth2Request = oAuthHelper.createOAuth2Request(username, password);
95 | oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);
96 | HttpServletRequest httpServletRequest = oAuthHelper.buildMockHttpServletRequest(username, password);
97 | OAuth2AuthenticationDetails oAuth2AuthenticationDetails = new OAuth2AuthenticationDetails(httpServletRequest);
98 | oAuth2Authentication.setDetails(oAuth2AuthenticationDetails);
99 |
100 | userTokenSession = new UserTokenSession(username, httpServletRequest.getHeader("Authorization"), "JSESSION : Test-123", Long.valueOf(tokenExpiryTime));
101 |
102 | httpHeaders = new HttpHeaders();
103 | httpHeaders.add("Authorization", httpServletRequest.getHeader("Authorization"));
104 | httpHeaders.add("cookie", "JSESSION : Test-123");
105 | }
106 |
107 |
108 |
109 | @Test
110 | public void testValidateToken() throws Exception {
111 |
112 | UserTokenSessionService.ValidMappingResponse expectedValidMappingResponse = new UserTokenSessionService.ValidMappingResponse(true, userTokenSession);
113 | Mockito.when(userTokenSessionService.isValidUserTokenSessionMapping(any())).thenReturn(expectedValidMappingResponse);
114 |
115 | this.mockMvc.perform(post("/oauth/validateToken").with(requestPostProcessor).principal(oAuth2Authentication).headers(httpHeaders))
116 | .andExpect(status().is(200))
117 | .equals(userTokenSession);
118 | }
119 |
120 | @Test
121 | public void testLogin() throws Exception {
122 |
123 | Mockito.when(userTokenSessionService.saveUserTokenSessionMapping(any())).thenReturn(userTokenSession);
124 |
125 | this.mockMvc.perform(post("/oauth/login").with(requestPostProcessor).principal(oAuth2Authentication).headers(httpHeaders))
126 | .andExpect(status().is(200))
127 | .equals(userTokenSession);
128 | }
129 |
130 |
131 | }
132 |
--------------------------------------------------------------------------------
/authentication/src/test/java/com/authentication/api/OAuthHelper.java:
--------------------------------------------------------------------------------
1 | package com.authentication.api;
2 |
3 | import com.authentication.api.AuthenticationAPI;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.beans.factory.annotation.Value;
6 | import org.springframework.mock.web.MockHttpServletRequest;
7 | import org.springframework.mock.web.MockHttpSession;
8 | import org.springframework.security.authentication.TestingAuthenticationToken;
9 | import org.springframework.security.core.Authentication;
10 | import org.springframework.security.oauth2.common.OAuth2AccessToken;
11 | import org.springframework.security.oauth2.provider.OAuth2Authentication;
12 | import org.springframework.security.oauth2.provider.OAuth2Request;
13 | import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
14 | import org.springframework.stereotype.Component;
15 | import org.springframework.test.web.servlet.request.RequestPostProcessor;
16 |
17 | import javax.servlet.http.HttpServletRequest;
18 | import java.util.HashMap;
19 | import java.util.HashSet;
20 | import java.util.Map;
21 | import java.util.Set;
22 |
23 | /**
24 | * Helper class for creating OAuth access token, OAuth Authentication, {@link MockHttpServletRequest} objects.
25 | */
26 | @Component
27 | public class OAuthHelper {
28 |
29 |
30 | @Value("${config.oauth2.clientID}")
31 | private String clientID;
32 |
33 | @Value("${config.oauth2.clientSecret}")
34 | private String clientSecret;
35 |
36 | @Value("${config.oauth2.resource.id}")
37 | private String resourceId;
38 |
39 | @Autowired
40 | private AuthorizationServerTokenServices tokenservice;
41 |
42 | /**
43 | * Create {@link RequestPostProcessor} for {@link AuthenticationAPI} testing.
44 | * @param username
45 | * @param password
46 | * @return
47 | */
48 | public RequestPostProcessor addBearerToken(final String username, String password) {
49 |
50 | RequestPostProcessor requestPostProcessor = new RequestPostProcessor() {
51 | @Override
52 | public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) {
53 |
54 | OAuth2Request oauth2Request = createOAuth2Request(username, password);
55 | Authentication userauth = new TestingAuthenticationToken(username, password);
56 | OAuth2Authentication oauth2auth = new OAuth2Authentication(oauth2Request, userauth);
57 | OAuth2AccessToken oAuth2AccessToken = tokenservice.createAccessToken(oauth2auth);
58 |
59 | request.addHeader("Authorization", "Bearer " + oAuth2AccessToken.getValue());
60 | request.setSession(new MockHttpSession());
61 | return request;
62 | }
63 | };
64 | return requestPostProcessor;
65 | }
66 |
67 | /**
68 | * Build {@link MockHttpServletRequest} for the given user with {@link OAuth2AccessToken}.
69 | * @param username
70 | * @param password
71 | * @return HttpServletRequest
72 | */
73 | public HttpServletRequest buildMockHttpServletRequest(final String username, String password) {
74 |
75 | MockHttpServletRequest httpServletRequest = new MockHttpServletRequest();//Mockito.mock(MockHttpServletRequest.class);
76 | OAuth2Request oauth2Request = createOAuth2Request(username, password);
77 | Authentication userauth = new TestingAuthenticationToken(username, password);
78 | OAuth2Authentication oauth2auth = new OAuth2Authentication(oauth2Request, userauth);
79 | OAuth2AccessToken oAuth2AccessToken = tokenservice.createAccessToken(oauth2auth);
80 |
81 | httpServletRequest.addHeader("Authorization", "Bearer " + oAuth2AccessToken.getValue());
82 | httpServletRequest.setSession(new MockHttpSession());
83 | return httpServletRequest;
84 | }
85 |
86 | /**
87 | * Create {@link OAuth2Request}
88 | * @param username
89 | * @param password
90 | * @return OAuth2Request
91 | */
92 | public OAuth2Request createOAuth2Request(String username, String password) {
93 |
94 | Map requestParams = new HashMap<>();
95 | requestParams.put("username", username);
96 | requestParams.put("password", password);
97 | requestParams.put("grant_type", "password");
98 | requestParams.put("client_id", clientID);
99 | requestParams.put("client_secret", clientSecret);
100 |
101 | Set scope = new HashSet<>();
102 | scope.add("read");
103 | scope.add("write");
104 |
105 | Set resourceIds = new HashSet<>();
106 | resourceIds.add(resourceId);
107 |
108 | OAuth2Request oauth2Request = new OAuth2Request(requestParams, clientID, null, true, scope, resourceIds, null, null, null);
109 |
110 | return oauth2Request;
111 | }
112 |
113 |
114 | }
--------------------------------------------------------------------------------
/authentication/src/test/java/com/authentication/service/UserDetailsServiceTest.java:
--------------------------------------------------------------------------------
1 | package com.authentication.service;
2 |
3 | import com.authentication.api.OAuthHelper;
4 | import com.authentication.model.User;
5 | import com.authentication.repository.UserRepository;
6 | import org.junit.Assert;
7 | import org.junit.Before;
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 | import org.mockito.InjectMocks;
11 | import org.mockito.Mockito;
12 | import org.mockito.MockitoAnnotations;
13 | import org.springframework.beans.factory.annotation.Autowired;
14 | import org.springframework.beans.factory.annotation.Value;
15 | import org.springframework.boot.test.context.SpringBootTest;
16 | import org.springframework.test.context.junit4.SpringRunner;
17 | import org.springframework.test.context.web.WebAppConfiguration;
18 | import org.springframework.util.ReflectionUtils;
19 |
20 | import java.io.IOException;
21 | import java.lang.reflect.Field;
22 |
23 | /**
24 | * @implNote This class provide Junits for {@link UserDetailsServiceImpl} class.
25 | * @author Rohit.Kumar
26 | *
27 | */
28 | @RunWith(SpringRunner.class)
29 | @WebAppConfiguration
30 | @SpringBootTest
31 | public class UserDetailsServiceTest {
32 |
33 | @InjectMocks
34 | private UserDetailsServiceImpl userDetailsService;
35 |
36 | private UserRepository userRepository;
37 |
38 | @Autowired
39 | private OAuthHelper oAuthHelper;
40 |
41 | @Value("${config.oauth2.tokenTimeout}")
42 | private String tokenExpiryTime;
43 |
44 | private User user;
45 |
46 | @Before
47 | public void setup() throws IOException {
48 |
49 | MockitoAnnotations.initMocks(this);
50 | userRepository = Mockito.mock(UserRepository.class);
51 |
52 | Field field = ReflectionUtils.findField(UserDetailsServiceImpl.class, "userRepository");
53 | ReflectionUtils.makeAccessible(field);
54 | ReflectionUtils.setField(field, userDetailsService, userRepository);
55 |
56 | user = Mockito.mock(User.class);
57 | }
58 |
59 | @Test
60 | public void testLoadUserByUsername() {
61 |
62 | String username = "dumy_user";
63 | Mockito.when(userRepository.findOneByUsername(username)).thenReturn(user);
64 |
65 | Assert.assertEquals(userDetailsService.loadUserByUsername(username), user);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/authentication/src/test/java/com/authentication/service/UserTokenSessionServiceTest.java:
--------------------------------------------------------------------------------
1 | package com.authentication.service;
2 |
3 | import com.authentication.api.OAuthHelper;
4 | import com.authentication.model.UserTokenSession;
5 | import com.authentication.repository.UserTokenSessionRepository;
6 | import org.junit.Assert;
7 | import org.junit.Before;
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 | import org.mockito.InjectMocks;
11 | import org.mockito.Mockito;
12 | import org.mockito.MockitoAnnotations;
13 | import org.springframework.beans.factory.annotation.Autowired;
14 | import org.springframework.beans.factory.annotation.Value;
15 | import org.springframework.boot.test.context.SpringBootTest;
16 | import org.springframework.security.core.userdetails.UsernameNotFoundException;
17 | import org.springframework.test.context.junit4.SpringRunner;
18 | import org.springframework.test.context.web.WebAppConfiguration;
19 | import org.springframework.util.ReflectionUtils;
20 |
21 | import javax.servlet.http.HttpServletRequest;
22 | import java.io.IOException;
23 | import java.lang.reflect.Field;
24 | import java.time.LocalDateTime;
25 |
26 | import static org.mockito.Matchers.any;
27 |
28 | /**
29 | * @implNote This class provide Junits for {@link UserTokenSessionServiceImpl} class.
30 | * @author Rohit.Kumar
31 | *
32 | */
33 | @RunWith(SpringRunner.class)
34 | @WebAppConfiguration
35 | @SpringBootTest
36 | public class UserTokenSessionServiceTest {
37 |
38 | private UserTokenSessionRepository userTokenSessionRepository;
39 |
40 | @InjectMocks
41 | private UserTokenSessionServiceImpl userTokenSessionService;
42 |
43 | @Autowired
44 | private OAuthHelper oAuthHelper;
45 |
46 | @Value("${config.oauth2.tokenTimeout}")
47 | private String tokenExpiryTime;
48 | private UserTokenSession userTokenSession;
49 |
50 | @Before
51 | public void setup() throws IOException {
52 |
53 | MockitoAnnotations.initMocks(this);
54 | userTokenSessionRepository = Mockito.mock(UserTokenSessionRepository.class);
55 | Field field = ReflectionUtils.findField(UserTokenSessionServiceImpl.class, "userTokenSessionRepository");
56 | ReflectionUtils.makeAccessible(field);
57 | ReflectionUtils.setField(field, userTokenSessionService, userTokenSessionRepository);
58 |
59 | /**
60 | * testIsValidUserTokenSessionMapping and testSaveUserTokenSessionMapping Set-up
61 | */
62 |
63 | String username = "user";
64 | String password = "password";
65 | HttpServletRequest httpServletRequest = oAuthHelper.buildMockHttpServletRequest(username, password);
66 | userTokenSession = new UserTokenSession(username, httpServletRequest.getHeader("Authorization"), "JSESSION : Test-123", Long.valueOf(tokenExpiryTime));
67 | }
68 |
69 | @Test(expected = UsernameNotFoundException.class)
70 | public void testIsValidUserTokenSessionMapping() {
71 |
72 | UserTokenSession mockUserTokenSession = Mockito.spy(userTokenSession);
73 | Mockito.when(userTokenSessionRepository.findOneByUsername(userTokenSession.getUsername())).thenReturn(mockUserTokenSession);
74 | Mockito.when(mockUserTokenSession.getCreatedTime()).thenReturn( LocalDateTime.now().plusDays(2));
75 |
76 | userTokenSessionService.isValidUserTokenSessionMapping(userTokenSession);
77 |
78 | }
79 |
80 | @Test
81 | public void testSaveUserTokenSessionMapping() {
82 |
83 | Mockito.when(userTokenSessionRepository.save(any(UserTokenSession.class))).thenReturn(userTokenSession);
84 | Assert.assertEquals(userTokenSessionService.saveUserTokenSessionMapping(userTokenSession), userTokenSession);
85 | }
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/authentication/src/test/resources/application.properties:
--------------------------------------------------------------------------------
1 | server.port=8080
2 | server.contextPath=/authenticateService
3 |
4 | logging.level.com.alfred=DEBUG
5 |
6 | # Data source properties
7 | spring.jpa.hibernate.ddl-auto=validate
8 | spring.jpa.show-sql=true
9 |
10 | # openssl genrsa -out jwt.pem 2048
11 | # openssl rsa -in jwt.pem
12 | config.oauth2.privateKey=MIICXQIBAAKBgQDNQZKqTlO/+2b4ZdhqGJzGBDltb5PZmBz1ALN2YLvt341pH6i5mO1V9cX5Ty1LM70fKfnIoYUP4KCE33dPnC7LkUwE/myh1zM6m8cbL5cYFPyP099thbVxzJkjHWqywvQih/qOOjliomKbM9pxG8Z1dB26hL9dSAZuA8xExjlPmQIDAQABAoGAImnYGU3ApPOVtBf/TOqLfne+2SZX96eVU06myDY3zA4rO3DfbR7CzCLE6qPnyDAIiW0UQBs0oBDdWOnOqz5YaePZu/yrLyj6KM6Q2e9ywRDtDh3ywrSfGpjdSvvoaeL1WesBWsgWv1vFKKvES7ILFLUxKwyCRC2Lgh7aI9GGZfECQQD84m98Yrehhin3fZuRaBNIu348Ci7ZFZmrvyxAIxrV4jBjpACW0RM2BvF5oYM2gOJqIfBOVjmPwUrobYEFcHRvAkEAz8jsfmxsZVwh3Y/Y47BzhKIC5FLaads541jNjVWfrPirljyCy1n4sg3WQH2IEyap3WTP84+csCtsfNfyK7fQdwJBAJNRyobY74cupJYkW5OK4OkXKQQLHp2iosJV/Y5jpQeC3JO/gARcSmfIBbbI66q9zKjtmpPYUXI4tc3PtUEY8QsCQQCcxySyC0sKe6bNzyC+Q8AVvkxiTKWiI5idEr8duhJd589H72Zc2wkMB+a2CEGo+Y5Hjy5cvuph/pG/7Qw7sljnAkAy/feClt1mUEiAcWrHRwcQ71AoA0+21yC9VkqPNrn3w7OEg8gBqPjRlXBNb00QieNeGGSkXOoU6gFschR22Dzy
13 |
14 | # openssl rsa -in jwt.pem -pubout
15 | config.oauth2.publicKey=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNQZKqTlO/+2b4ZdhqGJzGBDltb5PZmBz1ALN2YLvt341pH6i5mO1V9cX5Ty1LM70fKfnIoYUP4KCE33dPnC7LkUwE/myh1zM6m8cbL5cYFPyP099thbVxzJkjHWqywvQih/qOOjliomKbM9pxG8Z1dB26hL9dSAZuA8xExjlPmQIDAQAB
16 |
17 |
18 | #oauth configurations
19 | config.oauth2.tokenTimeout=3600
20 | config.oauth2.resource.id=oauth2-resource
21 | config.oauth2.clientID=client
22 | config.oauth2.clientSecret=secret
23 | security.oauth2.client.grantType=client_credentials
24 | config.oauth2.accessTokenUri=http://localhost:8080/authenticateService/oauth/token
25 | config.oauth2.userAuthorizationUri=http://localhost:8080/authenticateService/oauth/authorize
26 | config.oauth2.resourceURI= http://localhost:8080/authenticateService/oauth/authorize
27 |
--------------------------------------------------------------------------------
/oauthswager:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------