Skip to content

Commit

Permalink
Add all user attributes in the id_token if requested by RP
Browse files Browse the repository at this point in the history
  • Loading branch information
oharsta committed Aug 9, 2023
1 parent 4d74fa0 commit 9af7c0c
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 14 deletions.
11 changes: 7 additions & 4 deletions src/main/java/oidc/endpoints/TokenEndpoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ private ResponseEntity handleAuthorizationCodeGrant(AuthorizationCodeGrant autho

if (authorizationCode == null) {
/*
* Now it become's tricky. Did we get an 'null' because the code was bogus or because it was already
* Now it becomes tricky. Did we get an 'null' because the code was bogus or because it was already
* used? To both satisfy the - highly theoretical - risk of the audit race condition and the OIDC certification
* demand of deleting access_token issued with the re-used authorization code we need to query again.
*
Expand Down Expand Up @@ -298,9 +298,12 @@ private ResponseEntity handleClientCredentialsGrant(OpenIDClient client, TokenRe
return new ResponseEntity<>(body, responseHttpHeaders, HttpStatus.OK);
}

private Map<String, Object> tokenEndpointResponse(Optional<User> user, OpenIDClient client,
List<String> scopes, List<String> idTokenClaims,
boolean clientCredentials, String nonce,
private Map<String, Object> tokenEndpointResponse(Optional<User> user,
OpenIDClient client,
List<String> scopes,
List<String> idTokenClaims,
boolean clientCredentials,
String nonce,
Optional<Long> authorizationTime,
Optional<String> authorizationCodeId) {
Map<String, Object> map = new LinkedHashMap<>();
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/oidc/model/OpenIDClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public class OpenIDClient {

private boolean includeUnspecifiedNameID;
private boolean consentRequired;
private boolean claimsInIdToken;

public OpenIDClient(String clientId, List<String> redirectUrls, List<Scope> scopes, List<String> grants) {
this.clientId = clientId;
Expand Down Expand Up @@ -97,11 +98,11 @@ public OpenIDClient(Map<String, Object> root) {
this.signingCertificate = (String) metaDataFields.get("oidc:signingCertificate");
this.signingCertificateUrl = (String) metaDataFields.get("oidc:signingCertificateUrl");
this.consentRequired = parseBoolean(metaDataFields.get("oidc:consentRequired"));
this.claimsInIdToken = parseBoolean(metaDataFields.get("oidc:claims_in_id_token"));

this.includeUnspecifiedNameID = nameIdFormats.stream()
.filter(id -> metaDataFields.containsKey(id))
.map(id -> metaDataFields.get(id).equals("urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"))
.anyMatch(b -> b);
.filter(metaDataFields::containsKey)
.anyMatch(id -> metaDataFields.get(id).equals("urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"));
}

@Transient
Expand Down
18 changes: 12 additions & 6 deletions src/main/java/oidc/secure/TokenGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -416,14 +416,20 @@ private TokenValue idToken(OpenIDClient client, Optional<User> optionalUser, Map
builder.claim("scope", String.join(" ", scopes));
}

if (!CollectionUtils.isEmpty(idTokenClaims) && optionalUser.isPresent() && isAccessToken) {
if ((!CollectionUtils.isEmpty(idTokenClaims) || client.isClaimsInIdToken()) &&
optionalUser.isPresent() && isAccessToken) {
User user = optionalUser.get();
Map<String, Object> attributes = user.getAttributes();
idTokenClaims.forEach(claim -> {
if (attributes.containsKey(claim)) {
builder.claim(claim, attributes.get(claim));
}
});
if (!CollectionUtils.isEmpty(idTokenClaims)) {
idTokenClaims.forEach(claim -> {
if (attributes.containsKey(claim)) {
builder.claim(claim, attributes.get(claim));
}
});
}
if (client.isClaimsInIdToken()) {
attributes.forEach(builder::claim);
}
}

optionalUser.ifPresent(user -> {
Expand Down
16 changes: 15 additions & 1 deletion src/test/java/oidc/endpoints/TokenEndpointTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@

import static com.nimbusds.oauth2.sdk.auth.JWTAuthentication.CLIENT_ASSERTION_TYPE;
import static io.restassured.RestAssured.given;
import static java.util.Collections.emptyList;
import static org.junit.Assert.*;

@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -130,6 +131,19 @@ public void tokenWithClaims() throws IOException, ParseException, JOSEException,
assertEquals("Johhny", claimsSet.getClaim("nickname"));
}

@Test
public void claimsInIdToken() throws IOException, ParseException, JOSEException, BadJOSEException {
Response response = doAuthorizeWithClaims("student.mobility.rp.localhost", "code", null, null, null, emptyList());
String code = getCode(response);
Map<String, Object> body = doToken(code, "student.mobility.rp.localhost", "secret", GrantType.AUTHORIZATION_CODE);

String idToken = (String) body.get("id_token");
JWTClaimsSet claimsSet = processToken(idToken, port);

assertEquals("[email protected]", claimsSet.getClaim("email"));
assertEquals("Johhny", claimsSet.getClaim("nickname"));
}

@Test
public void clientCredentials() throws ParseException, IOException {
Map<String, Object> body = doToken(null, "mock-sp", "secret", GrantType.CLIENT_CREDENTIALS);
Expand Down Expand Up @@ -325,7 +339,7 @@ public void codeChallengeFlow() throws IOException {
CodeChallenge codeChallenge = CodeChallenge.compute(CodeChallengeMethod.S256, new CodeVerifier(verifier));

Response response = doAuthorizeWithClaimsAndScopesAndCodeChallengeMethod("mock-sp", "code", null, "nonce",
codeChallenge.getValue(), Collections.emptyList(), "openid", "state", CodeChallengeMethod.S256.getValue());
codeChallenge.getValue(), emptyList(), "openid", "state", CodeChallengeMethod.S256.getValue());
String code = getCode(response);
Map<String, Object> body = doToken(code, "mock-sp", null, GrantType.AUTHORIZATION_CODE, verifier);
assertTrue(body.containsKey("id_token"));
Expand Down
1 change: 1 addition & 0 deletions src/test/resources/manage/oidc10_rp.json
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@
],
"isResourceServer": "0",
"isPublicClient": false,
"oidc:claims_in_id_token": true,
"NameIDFormats:0": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified",
"NameIDFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
}
Expand Down

0 comments on commit 9af7c0c

Please sign in to comment.