Skip to content

Commit

Permalink
Customize tokens and user info
Browse files Browse the repository at this point in the history
  • Loading branch information
andifalk committed Dec 21, 2022
1 parent 2992426 commit 0fc1115
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.example.spring.authorizationserver.config;

import com.example.spring.authorizationserver.jose.Jwks;
import com.example.spring.authorizationserver.user.User;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.source.JWKSource;
Expand All @@ -17,9 +16,6 @@
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.crypto.password.PasswordEncoder;
Expand All @@ -32,29 +28,25 @@
import org.springframework.security.oauth2.server.authorization.JdbcOAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationConsentService;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcUserInfoAuthenticationContext;
import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcUserInfoAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
import org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat;
import org.springframework.security.oauth2.server.authorization.settings.TokenSettings;
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.util.matcher.RequestMatcher;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.function.Function;

@Configuration(proxyBeanMethods = false)
public class AuthorizationServerConfig {
Expand All @@ -78,33 +70,35 @@ public SecurityFilterChain h2ConsoleSecurityFilterChain(HttpSecurity http) throw
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE + 1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
.oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
RequestMatcher endpointsMatcher = authorizationServerConfigurer
.getEndpointsMatcher();

/*
authorizationServerConfigurer.oidc(
oidcConfigurer ->
oidcConfigurer.userInfoEndpoint(oidcUserInfoEndpointConfigurer ->
oidcUserInfoEndpointConfigurer.userInfoMapper(ac -> {
Map<String, Object> claims = new HashMap<>();
JwtAuthenticationToken jwtAuthenticationToken = (JwtAuthenticationToken) ac.getAuthentication().getPrincipal();
claims.put("sub", jwtAuthenticationToken.getToken().getSubject());
claims.put("name", jwtAuthenticationToken.getToken().getClaim("given_name") + " " +
jwtAuthenticationToken.getToken().getClaim("family_name"));
claims.put("family_name", jwtAuthenticationToken.getToken().getClaim("family_name"));
claims.put("given_name", jwtAuthenticationToken.getToken().getClaim("given_name"));
claims.put("email", jwtAuthenticationToken.getToken().getClaim("email"));
claims.put("roles", new ArrayList<>(jwtAuthenticationToken.getToken().getClaim("roles")));
return new OidcUserInfo(claims);
}))
);*/
Function<OidcUserInfoAuthenticationContext, OidcUserInfo> userInfoMapper = (context) -> {
OidcUserInfoAuthenticationToken authentication = context.getAuthentication();
JwtAuthenticationToken principal = (JwtAuthenticationToken) authentication.getPrincipal();

return new OidcUserInfo(principal.getToken().getClaims());
};

authorizationServerConfigurer
.oidc((oidc) -> oidc
.userInfoEndpoint((userInfo) -> userInfo
.userInfoMapper(userInfoMapper)
)
);
http
.securityMatcher(endpointsMatcher)
.authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated()
)
.csrf(csrf -> csrf.ignoringRequestMatchers(endpointsMatcher))
.exceptionHandling(exceptions ->
exceptions.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))
)
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
.apply(authorizationServerConfigurer);
return http.build();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.example.spring.authorizationserver.config;

import com.example.spring.authorizationserver.security.OidcUserInfoService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.core.oidc.OidcUserInfo;
import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;

import static org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames.ID_TOKEN;
import static org.springframework.security.oauth2.server.authorization.OAuth2TokenType.ACCESS_TOKEN;

@Configuration
public class JwtTokenCustomizerConfig {
@Bean
public OAuth2TokenCustomizer<JwtEncodingContext> tokenCustomizer(OidcUserInfoService userInfoService) {
return (context) -> {
if (ID_TOKEN.equals(context.getTokenType().getValue()) || ACCESS_TOKEN.equals(context.getTokenType())) {
OidcUserInfo userInfo = userInfoService.loadUser(
context.getPrincipal().getName());
context.getClaims().claims(claims ->
claims.putAll(userInfo.getClaims()));
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.example.spring.authorizationserver.security;

import com.example.spring.authorizationserver.user.User;
import org.springframework.security.oauth2.core.oidc.OidcUserInfo;
import org.springframework.stereotype.Service;

@Service
public class OidcUserInfoService {
private final AuthorizationServerUserDetailsService userDetailsService;

public OidcUserInfoService(AuthorizationServerUserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}

public OidcUserInfo loadUser(String username) {
User user = (User) userDetailsService.loadUserByUsername(username);
return OidcUserInfo.builder()
.subject(user.getIdentifier().toString())
.name(user.getFirstName() + " " + user.getLastName())
.givenName(user.getFirstName())
.familyName(user.getLastName())
.nickname(username)
.preferredUsername(username)
.profile("https://example.com/" + username)
.website("https://example.com")
.email(user.getEmail())
.emailVerified(true)
.claim("roles", user.getRoles())
.zoneinfo("Europe/Berlin")
.locale("de-DE")
.updatedAt("1970-01-01T00:00:00Z")
.build();
}
}

0 comments on commit 0fc1115

Please sign in to comment.