Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
Portals committed May 20, 2024
1 parent ad2385c commit 2d03e99
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 34 deletions.
53 changes: 53 additions & 0 deletions app/src/main/java/it/chalmers/gamma/app/oauth2/ClaimsMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package it.chalmers.gamma.app.oauth2;

import it.chalmers.gamma.app.user.domain.GammaUser;
import it.chalmers.gamma.app.user.domain.UserId;
import it.chalmers.gamma.app.user.domain.UserRepository;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;

@Controller
public class ClaimsMapper {

private final UserRepository userRepository;
private final String baseUrl;

private ClaimsMapper(
UserRepository userRepository, @Value("${application.base-uri}") String baseUrl) {
this.userRepository = userRepository;
this.baseUrl = baseUrl;
}

public Map<String, Object> generateClaims(List<String> scopes, UserId userId) {
GammaUser me = this.userRepository.get(userId).orElseThrow();

final String PROFILE_SCOPE = "SCOPE_profile";
final String EMAIL_SCOPE = "SCOPE_email";

Map<String, Object> claims = new HashMap<>();

for (String scope : scopes) {
if (scope.equals(PROFILE_SCOPE)) {
// https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
claims.put(
"name",
me.firstName().value() + " '" + me.nick().value() + "' " + me.lastName().value());
claims.put("given_name", me.firstName().value());
claims.put("family_name", me.lastName().value());
claims.put("nickname", me.nick().value());
claims.put("locale", me.language().toString().toLowerCase());
claims.put("picture", this.baseUrl + "/images/user/avatar/" + me.id().value());

// Non-standard claims.
claims.put("cid", me.cid().value());
} else if (scope.equals(EMAIL_SCOPE)) {
claims.put("email", me.extended().email().value());
}
}

return claims;
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package it.chalmers.gamma.app.oauth2;

import it.chalmers.gamma.app.user.domain.UserId;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.server.authorization.OAuth2TokenType;
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;

@Configuration
public class OAuth2AuthorizationServerSecurityConfig {
Expand All @@ -11,4 +15,20 @@ public class OAuth2AuthorizationServerSecurityConfig {
public AuthorizationServerSettings authorizationServerSettings() {
return AuthorizationServerSettings.builder().oidcUserInfoEndpoint("/oauth2/userinfo").build();
}

@Bean
public OAuth2TokenCustomizer<JwtEncodingContext> jwtTokenCustomizer(ClaimsMapper claimsMapper) {
return (context) -> {
if (OAuth2TokenType.ACCESS_TOKEN.equals(context.getTokenType())) {
context
.getClaims()
.claims(
(claims) ->
claims.putAll(
claimsMapper.generateClaims(
context.getAuthorizedScopes().stream().toList(),
UserId.valueOf(context.getAuthorization().getPrincipalName()))));
}
};
}
}
41 changes: 7 additions & 34 deletions app/src/main/java/it/chalmers/gamma/app/oauth2/UserInfoMapper.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package it.chalmers.gamma.app.oauth2;

import it.chalmers.gamma.app.user.domain.GammaUser;
import it.chalmers.gamma.app.user.domain.UserId;
import it.chalmers.gamma.app.user.domain.UserRepository;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.core.oidc.OidcUserInfo;
import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcUserInfoAuthenticationContext;
Expand All @@ -19,47 +16,23 @@
public class UserInfoMapper implements Function<OidcUserInfoAuthenticationContext, OidcUserInfo> {

private final UserRepository userRepository;
private final String baseUrl;
private final ClaimsMapper claimsMapper;

public UserInfoMapper(
UserRepository userRepository, @Value("${application.base-uri}") String baseUrl) {
public UserInfoMapper(UserRepository userRepository, ClaimsMapper claimsMapper) {
this.userRepository = userRepository;
this.baseUrl = baseUrl;
this.claimsMapper = claimsMapper;
}

public OidcUserInfo apply(OidcUserInfoAuthenticationContext context) {
OidcUserInfoAuthenticationToken authentication = context.getAuthentication();
JwtAuthenticationToken principal = (JwtAuthenticationToken) authentication.getPrincipal();
GammaUser me = this.userRepository.get(UserId.valueOf(principal.getName())).orElseThrow();

/*
* Available scopes are profile, email.
* The prefix that spring-authorization-server adds in SCOPE_
*/
final String PROFILE_SCOPE = "SCOPE_profile";
final String EMAIL_SCOPE = "SCOPE_email";

Map<String, Object> claims = new HashMap<>(principal.getToken().getClaims());
Collection<GrantedAuthority> scopes = principal.getAuthorities();

for (GrantedAuthority scope : scopes) {
if (scope.getAuthority().equals(PROFILE_SCOPE)) {
// https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
claims.put(
"name",
me.firstName().value() + " '" + me.nick().value() + "' " + me.lastName().value());
claims.put("given_name", me.firstName().value());
claims.put("family_name", me.lastName().value());
claims.put("nickname", me.nick().value());
claims.put("locale", me.language().toString().toLowerCase());
claims.put("picture", this.baseUrl + "/images/user/avatar/" + me.id().value());

// Non-standard claims.
claims.put("cid", me.cid().value());
} else if (scope.getAuthority().equals(EMAIL_SCOPE)) {
claims.put("email", me.extended().email().value());
}
}
claims.putAll(
this.claimsMapper.generateClaims(
principal.getAuthorities().stream().map(GrantedAuthority::getAuthority).toList(),
UserId.valueOf(principal.getName())));

return new OidcUserInfo(claims);
}
Expand Down

0 comments on commit 2d03e99

Please sign in to comment.