Skip to content

Commit 5f01f7a

Browse files
committed
Refactor README.md
1 parent 76e9aaf commit 5f01f7a

File tree

1 file changed

+66
-47
lines changed

1 file changed

+66
-47
lines changed

README.md

Lines changed: 66 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55

66
Customized from sample at [https://github.com/spring-projects/spring-authorization-server](https://github.com/spring-projects/spring-authorization-server).
77

8+
## Requirements
9+
10+
To run this server you need at least a Java 17 runtime as this project uses spring boot 3.x.
11+
812
## Usage
913

1014
Start the server by running the class _com.example.spring.authorizationserver.SpringAuthorizationServerApplication_.
@@ -48,11 +52,11 @@ __Please note__: Instead of _localhost_ the local ip _127.0.0.1_ is configured a
4852
This server already has preconfigured users.
4953
Therefore, to login please use one of these predefined credentials:
5054

51-
| Username | Email | Password | Role |
52-
| ---------| ------------------------ | -------- |--------|
53-
| bwayne | [email protected] | wayne | USER |
54-
| ckent | [email protected] | kent | USER |
55-
| pparker | [email protected] | parker | ADMIN |
55+
| Username | Email | Password | Roles |
56+
| ---------| ------------------------ | -------- |-------------|
57+
| bwayne | [email protected] | wayne | USER |
58+
| ckent | [email protected] | kent | USER |
59+
| pparker | [email protected] | parker | USER, ADMIN |
5660

5761
## Postman
5862

@@ -64,68 +68,83 @@ The collections (for both JWT and Opaque tokens) can be found in the _postman_ f
6468
The authorization server uses a persistent H2 (in-memory) storage for configuration and stored tokens.
6569

6670
You may have a look inside the data using the [H2 console](http://localhost:9000/h2-console).
67-
Please use ```jdbc:h2:mem:authzserver``` as jdbc url and _sa_ as user name, leave password empty.
71+
Please use ```jdbc:h2:mem:authzserver``` as jdbc url and _sa_ as username, leave password empty.
6872

6973
## Customizations
7074

71-
In the class _com.example.spring.authorizationserver.config.AuthorizationServerConfig_ you find some customizations.
72-
As currently there is no documentation available for spring authorization server this may be helpful information.
75+
This customized version contains an extended `user` object compared to the standard spring security `user` object.
76+
The contents of id and access tokens and user info endpoint information is customized for extended user data as well.
77+
78+
Check the spring [authorization server reference docs](https://docs.spring.io/spring-authorization-server/docs/current/reference/html/guides/how-to-userinfo.html) for more information.
7379

7480
### Configure information returned to the userinfo endpoint
7581

82+
__com.example.spring.authorizationserver.config.AuthorizationServerConfig:__
83+
7684
```java
77-
authorizationServerConfigurer.oidc(
78-
oidcConfigurer ->
79-
oidcConfigurer.userInfoEndpoint(oidcUserInfoEndpointConfigurer ->
80-
oidcUserInfoEndpointConfigurer.userInfoMapper(ac -> {
81-
Map<String, Object> claims = new HashMap<>();
82-
JwtAuthenticationToken jwtAuthenticationToken = (JwtAuthenticationToken) ac.getAuthentication().getPrincipal();
83-
claims.put("sub", jwtAuthenticationToken.getToken().getSubject());
84-
claims.put("name", jwtAuthenticationToken.getToken().getClaim("given_name") + " " +
85-
jwtAuthenticationToken.getToken().getClaim("family_name"));
86-
claims.put("family_name", jwtAuthenticationToken.getToken().getClaim("family_name"));
87-
claims.put("given_name", jwtAuthenticationToken.getToken().getClaim("given_name"));
88-
claims.put("email", jwtAuthenticationToken.getToken().getClaim("email"));
89-
claims.put("roles", jwtAuthenticationToken.getToken().getClaim("roles"));
90-
return new OidcUserInfo(claims);
91-
}))
92-
);
85+
@Configuration(proxyBeanMethods = false)
86+
public class AuthorizationServerConfig {
87+
@Bean
88+
@Order(Ordered.HIGHEST_PRECEDENCE + 1)
89+
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
90+
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
91+
new OAuth2AuthorizationServerConfigurer();
92+
RequestMatcher endpointsMatcher = authorizationServerConfigurer
93+
.getEndpointsMatcher();
94+
95+
Function<OidcUserInfoAuthenticationContext, OidcUserInfo> userInfoMapper = (context) -> {
96+
OidcUserInfoAuthenticationToken authentication = context.getAuthentication();
97+
JwtAuthenticationToken principal = (JwtAuthenticationToken) authentication.getPrincipal();
98+
99+
return new OidcUserInfo(principal.getToken().getClaims());
100+
};
101+
102+
authorizationServerConfigurer
103+
.oidc((oidc) -> oidc
104+
.userInfoEndpoint((userInfo) -> userInfo
105+
.userInfoMapper(userInfoMapper)
106+
)
107+
);
108+
http
109+
.securityMatcher(endpointsMatcher)
110+
.authorizeHttpRequests((authorize) -> authorize
111+
.anyRequest().authenticated()
112+
)
113+
.csrf(csrf -> csrf.ignoringRequestMatchers(endpointsMatcher))
114+
.exceptionHandling(exceptions ->
115+
exceptions.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))
116+
)
117+
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
118+
.apply(authorizationServerConfigurer);
119+
return http.build();
120+
}
121+
}
93122
```
94123

95-
### Customize id, access and refresh token contents
124+
### Customize id and access token contents
96125

97126
```java
98-
@Bean
99-
public OAuth2TokenCustomizer<JwtEncodingContext> jwtCustomizer() {
100-
return context -> {
101-
UsernamePasswordAuthenticationToken authentication = context.getPrincipal();
102-
LOGGER.info("Customizing {} for user {}", context.getTokenType(), authentication.getPrincipal());
103-
if (OAuth2TokenType.ACCESS_TOKEN.equals(context.getTokenType())) {
104-
context.getHeaders().header("typ", "jwt");
105-
context.getClaims().subject(((User) authentication.getPrincipal()).getIdentifier().toString());
106-
context.getClaims().claim("roles", ((User) authentication.getPrincipal()).getRoles());
107-
context.getClaims().claim("given_name", ((User) authentication.getPrincipal()).getFirstName());
108-
context.getClaims().claim("family_name", ((User) authentication.getPrincipal()).getLastName());
109-
context.getClaims().claim("email", ((User) authentication.getPrincipal()).getEmail());
110-
} else if (OAuth2TokenType.REFRESH_TOKEN.equals(context.getTokenType())) {
111-
// Nothing to do here
112-
} else {
113-
context.getHeaders().header("typ", "jwt");
114-
context.getClaims().subject(((User) authentication.getPrincipal()).getIdentifier().toString());
115-
context.getClaims().claim("roles", ((User) authentication.getPrincipal()).getRoles());
116-
context.getClaims().claim("given_name", ((User) authentication.getPrincipal()).getFirstName());
117-
context.getClaims().claim("family_name", ((User) authentication.getPrincipal()).getLastName());
118-
context.getClaims().claim("email", ((User) authentication.getPrincipal()).getEmail());
127+
@Configuration
128+
public class JwtTokenCustomizerConfig {
129+
@Bean
130+
public OAuth2TokenCustomizer<JwtEncodingContext> tokenCustomizer(OidcUserInfoService userInfoService) {
131+
return (context) -> {
132+
if (ID_TOKEN.equals(context.getTokenType().getValue()) || ACCESS_TOKEN.equals(context.getTokenType())) {
133+
OidcUserInfo userInfo = userInfoService.loadUser(
134+
context.getPrincipal().getName());
135+
context.getClaims().claims(claims ->
136+
claims.putAll(userInfo.getClaims()));
119137
}
120138
};
121139
}
140+
}
122141
```
123142

124143
## Feedback
125144

126145
Any feedback on this project is highly appreciated.
127146

128-
Just send an email to _andreas.falk(at)novatec-gmbh.de_ or contact me via Twitter (_@andifalk_).
147+
Just email _andreas.falk(at)novatec-gmbh.de_ or contact me via Twitter (_@andifalk_).
129148

130149
## License
131150

0 commit comments

Comments
 (0)