Skip to content

Commit 94afc41

Browse files
ss
1 parent 15aa351 commit 94afc41

File tree

6 files changed

+72
-28
lines changed

6 files changed

+72
-28
lines changed

README.md

+22-16
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
11
# Spring Security Oauth2 JPA Implementation
22

3-
> App-Token based OAuth2 POC built to grow with Spring Boot and ORM
3+
> App-Token based OAuth2 implementation built to grow with Spring Boot and JPA
4+
5+
## Table of Contents
6+
7+
- [Quick Start](#quick-start)
8+
- [Features](#features)
9+
- [Dependencies](#dependencies)
10+
- [Run the App](#run-the-app)
11+
- [API Guide](#api-guide)
12+
- [Registration](#registration)
13+
- [Implementations](#implementations)
14+
- [Mandatory Settings](#mandatory-settings)
15+
- [Customizable Settings](#customizable-settings)
16+
- [OAuth2 - ROPC](#oauth2---ropc)
17+
- [OAuth2 - Authorization Code](#oauth2---authorization-code)
18+
- [Running this App with Docker](#running-this-app-with-docker)
19+
- [Contribution Guide](#contribution-guide)
420

5-
## Supporting Oauth2 Type
6-
| ROPC | Authorization Code |
7-
|------------------|-------------------------------------------------|
8-
| production-level | Beta (expected to reach production-level in v3) |
921

1022
## Quick Start
1123
```xml
@@ -15,21 +27,15 @@
1527
<version>3.5.0</version>
1628
</dependency>
1729
```
18-
For v2, using the database tables from Spring Security 5 (only the database tables; follow the dependencies as above):
19-
```xml
20-
<dependency>
21-
<groupId>io.github.patternknife.securityhelper.oauth2.api</groupId>
22-
<artifactId>spring-security-oauth2-password-jpa-implementation</artifactId>
23-
<version>2.8.2</version>
24-
</dependency>
25-
```
2630

27-
## Overview
2831

29-
* Complete separation of the library (API) and the client for testing it
32+
## Features
33+
34+
* Complete separation of the library and the client
35+
* Library : API
36+
* Client : DOC, Integration tester
3037
* Immediate Permission (Authority) Check: Not limited to verifying the token itself, but also ensuring real-time validation of any updates to permissions in the database.
3138
* Token Introspector: Enable the ``/oauth2/introspect`` endpoint to allow multiple resource servers to verify the token's validity and permissions with the authorization server.
32-
3339
* 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`. (However, ``/oauth2/token`` is the standard that "spring-authorization-server" provides.)
3440
* As you are aware, the API ``/oauth2/token`` is what "spring-authorization-server" provides.
3541
* ``/api/v1/traditional-oauth/token`` is what this library implemented directly.

client/src/main/java/com/patternknife/securityhelper/oauth2/client/domain/customer/api/CustomerApi.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public Map<String, Boolean> logoutCustomer(HttpServletRequest request) {
103103

104104
@PreAuthorize("@resourceServerAuthorityChecker.hasRole('CUSTOMER_ADMIN')")
105105
@GetMapping("/customers/{id}")
106-
public CustomerResDTO.Id getCustomerForAuthorizationTest(@PathVariable("id") final long id, @CustomAuthenticationPrincipal KnifeUserInfo knifeUserInfo)
106+
public CustomerResDTO.Id getCustomerForAuthorizationTest(@PathVariable("id") final long id, @CustomAuthenticationPrincipal KnifeUserInfo<CustomizedUserInfo> knifeUserInfo)
107107
throws ResourceNotFoundException {
108108
return new CustomerResDTO.Id(id);
109109
}

lib/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ http://maven.apache.org/xsd/maven-4.0.0.xsd">
1010
<artifactId>spring-security-oauth2-password-jpa-implementation</artifactId>
1111
<version>3.5.0</version>
1212
<name>spring-security-oauth2-password-jpa-implementation</name>
13-
<description>The implementation of Spring Security 6 Spring Authorization Server for stateful OAuth2 Password Grant</description>
13+
<description>App-Token based OAuth2 implementation built to grow with Spring Boot and JPA</description>
1414
<packaging>jar</packaging>
1515

1616
<url>https://github.com/patternknife/spring-security-oauth2-password-jpa-implementation</url>

lib/src/main/java/io/github/patternknife/securityhelper/oauth2/api/config/security/server/ServerConfig.java

+33-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
package io.github.patternknife.securityhelper.oauth2.api.config.security.server;
22

33

4+
import com.nimbusds.jose.jwk.JWK;
5+
import com.nimbusds.jose.jwk.OctetSequenceKey;
6+
import com.nimbusds.jose.jwk.source.ImmutableSecret;
7+
import com.nimbusds.jose.jwk.source.JWKSource;
8+
import com.nimbusds.jose.proc.SecurityContext;
49
import io.github.patternknife.securityhelper.oauth2.api.config.security.aop.DefaultSecurityPointCut;
510
import io.github.patternknife.securityhelper.oauth2.api.config.security.aop.SecurityPointCut;
611
import io.github.patternknife.securityhelper.oauth2.api.config.security.converter.auth.endpoint.AuthorizationCodeAuthorizationRequestConverter;
@@ -47,7 +52,10 @@
4752
import org.springframework.security.crypto.password.PasswordEncoder;
4853
import org.springframework.security.oauth2.core.OAuth2Token;
4954

55+
import org.springframework.security.oauth2.jwt.JwtEncoder;
56+
import org.springframework.security.oauth2.jwt.NimbusJwtEncoder;
5057
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
58+
import org.springframework.security.oauth2.server.authorization.token.JwtGenerator;
5159
import org.springframework.security.oauth2.server.authorization.token.OAuth2AccessTokenGenerator;
5260
import org.springframework.security.oauth2.server.authorization.token.OAuth2RefreshTokenGenerator;
5361
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
@@ -63,6 +71,9 @@
6371

6472
import org.springframework.web.servlet.HandlerExceptionResolver;
6573

74+
import javax.crypto.SecretKey;
75+
import javax.crypto.spec.SecretKeySpec;
76+
import java.util.Base64;
6677

6778

6879
@Configuration
@@ -74,17 +85,36 @@ public class ServerConfig {
7485

7586
private static String CUSTOM_CONSENT_PAGE_URI = "/oauth2/authorization";
7687

88+
7789
@Primary
7890
@Bean
7991
public OAuth2TokenGenerator<OAuth2Token> tokenGenerator() {
80-
OAuth2AccessTokenGenerator accessTokenGenerator = new OAuth2AccessTokenGenerator();
81-
OAuth2RefreshTokenGenerator refreshTokenGenerator = new OAuth2RefreshTokenGenerator();
92+
// Base64-encoded secret key (HS256)
93+
String secretKey = "U29tZVZhbGlkU2VjcmV0S2V5IQ=="; // Replace with your Base64-encoded secret key
94+
byte[] decodedKey = Base64.getDecoder().decode(secretKey);
95+
96+
// Create JWK from the secret key
97+
JWK jwk = new OctetSequenceKey.Builder(decodedKey).build();
98+
99+
// Create JWKSource
100+
JWKSource<SecurityContext> jwkSource = new ImmutableSecret<>(decodedKey);
101+
102+
// Create JwtEncoder with the JWKSource
103+
JwtEncoder jwtEncoder = new NimbusJwtEncoder(jwkSource);
104+
105+
// Create JwtGenerator with the JwtEncoder
106+
JwtGenerator jwtGenerator = new JwtGenerator(jwtEncoder);
107+
108+
// Combine JwtGenerator with a RefreshTokenGenerator
82109
return new CustomDelegatingOAuth2TokenGenerator(
83-
accessTokenGenerator, refreshTokenGenerator);
110+
jwtGenerator,
111+
new OAuth2RefreshTokenGenerator()
112+
);
84113
}
85114

86115

87116

117+
88118
@Bean
89119
@Order(1)
90120
public SecurityFilterChain authorizationServerSecurityFilterChain(

lib/src/main/java/io/github/patternknife/securityhelper/oauth2/api/config/security/token/generator/CustomAccessTokenCustomizer.java

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11
package io.github.patternknife.securityhelper.oauth2.api.config.security.token.generator;
22

33
import org.springframework.security.core.userdetails.UserDetails;
4+
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;
45
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenClaimsContext;
56
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenClaimsSet;
67
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;
78

89
import java.util.HashMap;
910
import java.util.Map;
1011

11-
public class CustomAccessTokenCustomizer implements OAuth2TokenCustomizer<OAuth2TokenClaimsContext> {
12+
public class CustomAccessTokenCustomizer implements OAuth2TokenCustomizer<JwtEncodingContext> {
1213

1314
private final UserDetails userDetails;
1415

1516
public CustomAccessTokenCustomizer(UserDetails userDetails) {
1617
this.userDetails = userDetails;
1718
}
1819

19-
@Override
20+
21+
22+
/* @Override
2023
public void customize(OAuth2TokenClaimsContext context) {
2124
if (context != null) {
2225
OAuth2TokenClaimsSet.Builder claimsSetBuilder = context.getClaims();
@@ -32,7 +35,7 @@ public void customize(OAuth2TokenClaimsContext context) {
3235
}
3336
3437
35-
}
38+
}*/
3639
private Map<String, Object> serializeCustomerToMap(UserDetails userDetails) {
3740
// Implement the logic to transform the Customer object into a Map or another format suitable for JWT claims
3841
Map<String, Object> customerInfo = new HashMap<>();
@@ -41,4 +44,9 @@ private Map<String, Object> serializeCustomerToMap(UserDetails userDetails) {
4144
// Add other customer attributes as needed
4245
return customerInfo;
4346
}
47+
48+
@Override
49+
public void customize(JwtEncodingContext context) {
50+
51+
}
4452
}

lib/src/main/java/io/github/patternknife/securityhelper/oauth2/api/config/security/token/generator/CustomDelegatingOAuth2TokenGenerator.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public OAuth2Token generate(OAuth2TokenContext context) {
3232
boolean b = tokenGenerators.get(0) instanceof CustomDelegatingOAuth2TokenGenerator;
3333
if(b){
3434
CustomDelegatingOAuth2TokenGenerator c = (CustomDelegatingOAuth2TokenGenerator) tokenGenerators.get(0);
35-
boolean d = c.tokenGenerators.get(0) instanceof OAuth2AccessTokenGenerator;
35+
boolean d = c.tokenGenerators.get(0) instanceof JwtGenerator;
3636
boolean e = c.tokenGenerators.get(1) instanceof OAuth2RefreshTokenGenerator;
3737
if(d && context.getTokenType().equals(OAuth2TokenType.ACCESS_TOKEN)){
3838
return ((OAuth2AccessTokenGenerator) c.tokenGenerators.get(0)).generate(context);
@@ -47,17 +47,17 @@ public OAuth2Token generate(OAuth2TokenContext context) {
4747
return null;
4848
}
4949

50-
public void setCustomizer(GeneratorType type, OAuth2TokenCustomizer<OAuth2TokenClaimsContext> customizer) {
50+
public void setCustomizer(GeneratorType type, OAuth2TokenCustomizer<JwtEncodingContext> customizer) {
5151
switch (type) {
5252
case ACCESS_TOKEN:
5353
for (OAuth2TokenGenerator<? extends OAuth2Token> tokenGenerator : this.tokenGenerators) {
5454
if (tokenGenerator instanceof CustomDelegatingOAuth2TokenGenerator) {
5555
boolean b = tokenGenerators.get(0) instanceof CustomDelegatingOAuth2TokenGenerator;
5656
if(b){
5757
CustomDelegatingOAuth2TokenGenerator c = (CustomDelegatingOAuth2TokenGenerator) tokenGenerators.get(0);
58-
boolean d = c.tokenGenerators.get(0) instanceof OAuth2AccessTokenGenerator;
58+
boolean d = c.tokenGenerators.get(0) instanceof JwtGenerator;
5959
if(d){
60-
((OAuth2AccessTokenGenerator) c.tokenGenerators.get(0)).setAccessTokenCustomizer(customizer);
60+
((JwtGenerator) c.tokenGenerators.get(0)).setJwtCustomizer(customizer);
6161
}
6262
}
6363
}

0 commit comments

Comments
 (0)