Skip to content

Commit e384d11

Browse files
ci/cd : the first publish
1 parent 6cfa1de commit e384d11

File tree

74 files changed

+329
-259
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+329
-259
lines changed

README.md

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,46 @@
1-
# POC : Spring Security Oauth2 Password JPA Implementation
1+
# Spring Security Oauth2 Password JPA Implementation
22
## Overview
33

4-
* In the Spring Security 6 ecosystem, compared to 5, there is a preference for JWT or Keycloak over traditional OAuth2 using a Password Grant method with Spring Security Authorization and Resource Server. I needed to incorporate the current OAuth2 Password Grant with the Spring Security new version and am showing the customization.
5-
* Set up access & refresh token APIs on both '/oauth2/token' and on our controller layer such as '/api/v1...', both of which function same and have `the same request & response payloads for success and errors`.
6-
* In the following error payload, the 'message' shouldn't be exposed to clients; instead, the 'userMessage' should be.
7-
````
8-
{
9-
"timestamp": 1719470948370,
10-
"message": "Couldn't find the client ID : client_admi",
11-
"details": "uri=/oauth2/token",
12-
"userMessage": "Authentication failed. Please check your credentials.",
13-
"userValidationMessage": null
14-
}
15-
````
16-
* Authentication management based on a combination of username, client id, and an extra token (referred to in the source code as App-Token, which receives a unique value from the calling devices).
17-
* Separated UserDetails implementation for Admin and Customer roles.
18-
* Integration with spring-security-oauth2-authorization-server.
19-
* Provide MySQL DDL, which consists of oauth\_access\_token, oauth\_refresh\_token and oauth\_client\_details, which is tables in Security 5. As I mean to migrate current security system to Security 6, I haven't changed them to the ``authorization`` table indicated in https://github.com/spring-projects/spring-authorization-server.
20-
* Application of Spring Rest Docs.
4+
* Complete separation of the library (API) and the client for testing it
5+
```xml
6+
<dependency>
7+
<groupId>io.github.patternknife.securityhelper.oauth2.api</groupId>
8+
<artifactId>spring-security-oauth2-password-jpa-implementation</artifactId>
9+
<version>2.4.0</version>
10+
</dependency>
11+
```
12+
* Set up the same access & refresh token APIs on both ``/oauth2/token`` and on our controller layer such as ``/api/v1/traditional-oauth/token``, both of which function same and have `the same request & response payloads for success and errors`.
13+
* As you are aware, the API ``/oauth2/token`` is what "spring-authorization-server" provides.
14+
* ``/api/v1/traditional-oauth/token`` is what this library implemented manually.
15+
* Success Payload
16+
```json
17+
{
18+
"access_token" : "Vd4x8D4lDg7VBFh...",
19+
"token_type" : "Bearer",
20+
"refresh_token" : "m3UgLrvPtXKdy7jiD...",
21+
"expires_in" : 3469,
22+
"scope" : "read write"
23+
}
24+
```
25+
26+
* Error Payload
27+
```json
28+
{
29+
"timestamp": 1719470948370,
30+
"message": "Couldn't find the client ID : client_admin", // Sensitive info such as being thrown from StackTraces
31+
"details": "uri=/oauth2/token",
32+
"userMessage": "Authentication failed. Please check your credentials.",
33+
"userValidationMessage": null
34+
}
35+
```
36+
37+
* In the following error payload, the 'message' shouldn't be exposed to clients; instead, the 'userMessage' should be.
38+
39+
* Authentication management based on a combination of username, client ID, and App-Token
40+
* What is an App-Token? An App-Token is a new access token generated each time the same account logs in. If the token values are the same, the same access token is shared.
41+
* Separated UserDetails implementation for Admin and Customer roles as an example. (This can be extended as desired by implementing ``UserDetailsServiceFactory``)
42+
* Provide MySQL DDL, which consists of oauth\_access\_token, oauth\_refresh\_token and oauth\_client\_details, which is tables in Security 5. As I mean to migrate current security system to Security 6, I haven't changed them to the ``authorization`` table indicated in https://github.com/spring-projects/spring-authorization-server.
43+
* Application of Spring Rest Docs
2144

2245
## Dependencies
2346

@@ -47,16 +70,16 @@ mvnw clean install # Integration tests are done here, which creates docs by Spri
4770
- In case you use IntelliJ, I recommend creating an empty project and importing the API (root) module and client module separately.
4871
- The client module definitely consumes the API module, but not vice versa.
4972

50-
## Implementation of the Api
51-
### The implementation method is shown in the client source code.
73+
## API Guide
74+
#### The implementation method is shown in the client source code.
5275

53-
- **Registration**
54-
- As the Api consumes JPA, adding it to Beans is required.
76+
### **Registration**
77+
- As the Api module consumes JPA, adding it to Beans is required.
5578

5679
```java
5780

58-
// ADD 'com.patternknife.securityhelper.oauth2.api'
59-
@SpringBootApplication(scanBasePackages = {"com.patternknife.securityhelper.oauth2.client", "com.patternknife.securityhelper.oauth2.api"})
81+
// ADD 'io.github.patternknife.securityhelper.oauth2.api'
82+
@SpringBootApplication(scanBasePackages = {"com.patternknife.securityhelper.oauth2.client", "io.github.patternknife.securityhelper.oauth2.api"})
6083
public class SpringSecurityOauth2PasswordJpaImplApplication {
6184

6285
public static void main(String[] args) {
@@ -68,39 +91,43 @@ public class SpringSecurityOauth2PasswordJpaImplApplication {
6891

6992
```java
7093
@Configuration
71-
// ADD 'com.patternknife.securityhelper.oauth2.api.config.security'
94+
// ADD 'io.github.patternknife.securityhelper.oauth2.api.config.security'
7295
@EnableJpaRepositories(
7396
basePackages = {"com.patternknife.securityhelper.oauth2.client.domain",
7497
"com.patternknife.securityhelper.oauth2.client.config.securityimpl",
75-
"com.patternknife.securityhelper.oauth2.api.config.security"},
98+
"io.github.patternknife.securityhelper.oauth2.api.config.security"},
7699
entityManagerFactoryRef = "commonEntityManagerFactory",
77100
transactionManagerRef= "commonTransactionManager"
78101
)
79102
public class CommonDataSourceConfiguration {
80103

81104

82-
// ADD 'com.patternknife.securityhelper.oauth2.api.config.security'
105+
// ADD 'io.github.patternknife.securityhelper.oauth2.api.config.security'
83106
@Primary
84107
@Bean(name = "commonEntityManagerFactory")
85108
public LocalContainerEntityManagerFactoryBean commonEntityManagerFactory(EntityManagerFactoryBuilder builder) {
86109
return builder
87110
.dataSource(commonDataSource())
88111
.packages("com.patternknife.securityhelper.oauth2.client.domain",
89-
"com.patternknife.securityhelper.oauth2.api.config.security")
112+
"io.github.patternknife.securityhelper.oauth2.api.config.security")
90113
.persistenceUnit("commonEntityManager")
91114
.build();
92115
}
93116

94117
}
95118
```
96119

97-
- **Implementation**
98-
- In fact, the only mandatory settings are 'CustomUserDetailsServiceFactory'. The rest depend on your specific situation.
99-
100-
![img.png](reference/docs/img.png)
101-
102-
103-
### Running this App with Docker
120+
### **Implementation**
121+
- The only mandatory setting is ``client.config.securityimpl.service.userdetail.CustomUserDetailsServiceFactory``. The rest depend on your specific situation.
122+
123+
- **Use PointCut when events happen such as tokens created**
124+
- ``SecurityPointCut``
125+
- See the source code in ``client.config.securityimpl.aop``
126+
- **Register error user messages as desired**
127+
- ``ISecurityUserExceptionMessageService``
128+
- See the source code in ``client.config.securityimpl.message``
129+
130+
## Running this App with Docker
104131
* Use the following module for Blue-Green deployment:
105132
* https://github.com/patternknife/docker-blue-green-runner
106133
* The above module references this app's Dockerfile and the entrypoint script in the .docker folder.

client/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ http://maven.apache.org/xsd/maven-4.0.0.xsd">
77
<modelVersion>4.0.0</modelVersion>
88
<groupId>com.patternknife.securityhelper.oauth2.client</groupId>
99
<artifactId>spring-security-oauth2-password-jpa-implementation-client</artifactId>
10-
<version>2.3.0</version>
10+
<version>2.4.0</version>
1111
<packaging>jar</packaging>
1212

1313
<properties>
@@ -39,9 +39,9 @@ http://maven.apache.org/xsd/maven-4.0.0.xsd">
3939

4040
<dependencies>
4141
<dependency>
42-
<groupId>com.patternknife.securityhelper.oauth2.api</groupId>
42+
<groupId>io.github.patternknife.securityhelper.oauth2.api</groupId>
4343
<artifactId>spring-security-oauth2-password-jpa-implementation</artifactId>
44-
<version>2.3.0</version>
44+
<version>2.4.0</version>
4545
</dependency>
4646

4747
<!-- DB -->

client/src/main/java/com/patternknife/securityhelper/oauth2/client/SpringSecurityOauth2PasswordJpaImplApplication.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import java.util.TimeZone;
88

99

10-
@SpringBootApplication(scanBasePackages = {"com.patternknife.securityhelper.oauth2.client", "com.patternknife.securityhelper.oauth2.api"})
10+
@SpringBootApplication(scanBasePackages = {"com.patternknife.securityhelper.oauth2.client", "io.github.patternknife.securityhelper.oauth2.api"})
1111
public class SpringSecurityOauth2PasswordJpaImplApplication {
1212

1313
@PostConstruct

client/src/main/java/com/patternknife/securityhelper/oauth2/client/config/database/CommonDataSourceConfiguration.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
@EnableJpaRepositories(
2323
basePackages = {"com.patternknife.securityhelper.oauth2.client.domain",
2424
"com.patternknife.securityhelper.oauth2.client.config.securityimpl",
25-
"com.patternknife.securityhelper.oauth2.api.config.security"},
25+
"io.github.patternknife.securityhelper.oauth2.api.config.security"},
2626
entityManagerFactoryRef = "commonEntityManagerFactory",
2727
transactionManagerRef= "commonTransactionManager"
2828
)
@@ -49,7 +49,7 @@ public LocalContainerEntityManagerFactoryBean commonEntityManagerFactory(EntityM
4949
return builder
5050
.dataSource(commonDataSource())
5151
.packages("com.patternknife.securityhelper.oauth2.client.domain",
52-
"com.patternknife.securityhelper.oauth2.api.config.security")
52+
"io.github.patternknife.securityhelper.oauth2.api.config.security")
5353
.persistenceUnit("commonEntityManager")
5454
.build();
5555
}

client/src/main/java/com/patternknife/securityhelper/oauth2/client/config/response/error/dto/CustomErrorResponsePayload.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33

44
import com.fasterxml.jackson.annotation.JsonIgnore;
5-
import com.patternknife.securityhelper.oauth2.api.config.response.TimestampUtil;
6-
import com.patternknife.securityhelper.oauth2.api.config.response.error.dto.ErrorMessages;
5+
import io.github.patternknife.securityhelper.oauth2.api.config.response.TimestampUtil;
6+
import io.github.patternknife.securityhelper.oauth2.api.config.response.error.dto.ErrorMessages;
77

88
import lombok.ToString;
99
import org.apache.commons.lang3.StringUtils;

client/src/main/java/com/patternknife/securityhelper/oauth2/client/config/response/error/exception/ErrorMessagesContainedException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.patternknife.securityhelper.oauth2.client.config.response.error.exception;
22

3-
import com.patternknife.securityhelper.oauth2.api.config.response.error.dto.ErrorMessages;
3+
import io.github.patternknife.securityhelper.oauth2.api.config.response.error.dto.ErrorMessages;
44

55
public abstract class ErrorMessagesContainedException extends RuntimeException {
66

client/src/main/java/com/patternknife/securityhelper/oauth2/client/config/response/error/exception/data/ResourceNotFoundException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.patternknife.securityhelper.oauth2.client.config.response.error.exception.data;
22

3-
import com.patternknife.securityhelper.oauth2.api.config.response.error.dto.ErrorMessages;
3+
import io.github.patternknife.securityhelper.oauth2.api.config.response.error.dto.ErrorMessages;
44
import com.patternknife.securityhelper.oauth2.client.config.response.error.exception.ErrorMessagesContainedException;
55
import org.springframework.http.HttpStatus;
66
import org.springframework.web.bind.annotation.ResponseStatus;

client/src/main/java/com/patternknife/securityhelper/oauth2/client/config/response/error/exception/util/EncodingProcessException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.patternknife.securityhelper.oauth2.client.config.response.error.exception.util;
22

3-
import com.patternknife.securityhelper.oauth2.api.config.security.message.ExceptionMessageInterface;
3+
import io.github.patternknife.securityhelper.oauth2.api.config.security.message.ExceptionMessageInterface;
44
import org.springframework.http.HttpStatus;
55
import org.springframework.web.bind.annotation.ResponseStatus;
66

client/src/main/java/com/patternknife/securityhelper/oauth2/client/config/response/error/message/GeneralErrorMessage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.patternknife.securityhelper.oauth2.client.config.response.error.message;
22

3-
import com.patternknife.securityhelper.oauth2.api.config.security.message.ExceptionMessageInterface;
3+
import io.github.patternknife.securityhelper.oauth2.api.config.security.message.ExceptionMessageInterface;
44
import lombok.Getter;
55
import org.springframework.http.HttpStatus;
66

client/src/main/java/com/patternknife/securityhelper/oauth2/client/config/securityimpl/aop/SecurityPointCutImpl.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package com.patternknife.securityhelper.oauth2.client.config.securityimpl.aop;
22

33

4-
import com.patternknife.securityhelper.oauth2.api.config.security.aop.SecurityPointCut;
5-
import com.patternknife.securityhelper.oauth2.api.config.security.entity.CustomOauthAccessToken;
6-
import com.patternknife.securityhelper.oauth2.api.config.security.entity.CustomOauthRefreshToken;
7-
import com.patternknife.securityhelper.oauth2.api.config.security.entity.OauthClientDetail;
4+
import io.github.patternknife.securityhelper.oauth2.api.config.security.aop.SecurityPointCut;
5+
import io.github.patternknife.securityhelper.oauth2.api.config.security.entity.CustomOauthAccessToken;
6+
import io.github.patternknife.securityhelper.oauth2.api.config.security.entity.CustomOauthRefreshToken;
7+
import io.github.patternknife.securityhelper.oauth2.api.config.security.entity.OauthClientDetail;
88

99
import jakarta.annotation.Nullable;
1010
import lombok.RequiredArgsConstructor;

0 commit comments

Comments
 (0)