Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FISH-5725: adding code to support get Claims from ID Token #137

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ buildNumber.properties
# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
!/.mvn/wrapper/maven-wrapper.jar
*.iml
.idea
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Payara Foundation and/or its affiliates. All rights reserved.
* Copyright (c) 2021 Payara Foundation and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
Expand Down Expand Up @@ -169,6 +169,11 @@ public boolean tokenAutoRefresh() {
public int tokenMinValidity() {
return azureDefinition.tokenMinValidity();
}

@Override
public boolean userClaimsFromIDToken() {
return azureDefinition.userClaimsFromIDToken();
}
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Payara Foundation and/or its affiliates. All rights reserved.
* Copyright (c) 2021 Payara Foundation and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
Expand Down Expand Up @@ -157,6 +157,11 @@ public boolean tokenAutoRefresh() {
public int tokenMinValidity() {
return googleDefinition.tokenMinValidity();
}

@Override
public boolean userClaimsFromIDToken() {
return googleDefinition.userClaimsFromIDToken();
}
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Payara Foundation and/or its affiliates. All rights reserved.
* Copyright (c) 2021 Payara Foundation and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
Expand Down Expand Up @@ -215,6 +215,7 @@ public OpenIdConfiguration buildConfig(OpenIdAuthenticationDefinition definition

boolean tokenAutoRefresh = OpenIdUtil.getConfiguredValue(Boolean.class, definition.tokenAutoRefresh(), provider, OpenIdAuthenticationDefinition.OPENID_MP_TOKEN_AUTO_REFRESH);
int tokenMinValidity = OpenIdUtil.getConfiguredValue(Integer.class, definition.tokenMinValidity(), provider, OpenIdAuthenticationDefinition.OPENID_MP_TOKEN_MIN_VALIDITY);
boolean userClaimsFromIDToken = OpenIdUtil.getConfiguredValue(Boolean.class, definition.userClaimsFromIDToken(), provider, OpenIdAuthenticationDefinition.OPENID_MP_USER_CLAIMS_FROM_ID_TOKEN);

OpenIdConfiguration configuration = new OpenIdConfiguration()
.setProviderMetadata(
Expand Down Expand Up @@ -256,7 +257,8 @@ public OpenIdConfiguration buildConfig(OpenIdAuthenticationDefinition definition
.setJwksConnectTimeout(jwksConnectTimeout)
.setJwksReadTimeout(jwksReadTimeout)
.setTokenAutoRefresh(tokenAutoRefresh)
.setTokenMinValidity(tokenMinValidity);
.setTokenMinValidity(tokenMinValidity)
.setUserClaimsFromIDToken(userClaimsFromIDToken);

validateConfiguration(configuration);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Payara Foundation and/or its affiliates. All rights reserved.
* Copyright (c) 2021 Payara Foundation and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
Expand Down Expand Up @@ -70,6 +70,7 @@ public class OpenIdConfiguration {
private boolean tokenAutoRefresh;
private int tokenMinValidity;
private JWTValidator validator;
private boolean userClaimsFromIDToken;

static final String BASE_URL_EXPRESSION = "${baseURL}";

Expand Down Expand Up @@ -253,6 +254,15 @@ public OpenIdConfiguration setTokenMinValidity(int tokenMinValidity) {
return this;
}

public boolean isUserClaimsFromIDToken() {
return userClaimsFromIDToken;
}

public OpenIdConfiguration setUserClaimsFromIDToken(boolean userClaimsFromIDToken) {
this.userClaimsFromIDToken = userClaimsFromIDToken;
return this;
}

@Override
public String toString() {
return OpenIdConfiguration.class.getSimpleName()
Expand All @@ -273,6 +283,7 @@ public String toString() {
+ ", encryptionMetadata=" + encryptionMetadata
+ ", tokenAutoRefresh=" + tokenAutoRefresh
+ ", tokenMinValidity=" + tokenMinValidity
+ ", userClaimsFromIDToken=" + userClaimsFromIDToken
+ '}';
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Payara Foundation and/or its affiliates. All rights reserved.
* Copyright (c) 2021 Payara Foundation and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
Expand Down Expand Up @@ -42,13 +42,15 @@
import fish.payara.security.openid.api.OpenIdClaims;
import fish.payara.security.openid.api.OpenIdContext;
import fish.payara.security.openid.api.RefreshToken;
import fish.payara.security.openid.api.JwtClaims;
import fish.payara.security.openid.api.OpenIdConstant;
import fish.payara.security.openid.controller.AuthenticationController;
import fish.payara.security.openid.OpenIdUtil;
import fish.payara.security.openid.api.OpenIdConstant;
import fish.payara.security.openid.controller.UserInfoController;

import java.io.IOException;
import java.util.Optional;
import static java.util.logging.Level.FINEST;
import static java.util.logging.Level.WARNING;
import java.util.logging.Logger;
import java.util.Set;
Expand Down Expand Up @@ -162,14 +164,41 @@ public void setExpiresIn(Long expiresIn) {
public JsonObject getClaimsJson() {
if (claims == null) {
if (configuration != null && accessToken != null) {
claims = userInfoController.getUserInfo(configuration, accessToken);
if(!configuration.isUserClaimsFromIDToken()) {
claims = userInfoController.getUserInfo(configuration, accessToken);
} else {
LOGGER.log(FINEST, "Processing user info from ID Token");
claims = processUserClaimsFromIDToken();
}
} else {
claims = Json.createObjectBuilder().build();
}
}
return claims;
}

/**
* Method to get user information from Id Token
* @return JsonObject with user information
*/
private JsonObject processUserClaimsFromIDToken() {
JwtClaims identityTokenJWTClaims = identityToken.getJwtClaims();
JwtClaims accessTokenJWTClaims = accessToken.getJwtClaims();
//setting profile claims from id token
JsonObject userInfo = Json.createObjectBuilder()
.add(OpenIdConstant.SUBJECT_IDENTIFIER, identityTokenJWTClaims.getStringClaim(OpenIdConstant.SUBJECT_IDENTIFIER).orElse(""))
.add(OpenIdConstant.NAME, identityTokenJWTClaims.getStringClaim(OpenIdConstant.NAME).orElse(""))
.add(OpenIdConstant.FAMILY_NAME, accessTokenJWTClaims.getStringClaim(OpenIdConstant.FAMILY_NAME).orElse(""))
.add(OpenIdConstant.GIVEN_NAME, accessTokenJWTClaims.getStringClaim(OpenIdConstant.GIVEN_NAME).orElse(""))
.add(OpenIdConstant.EMAIL, identityTokenJWTClaims.getStringClaim(OpenIdConstant.EMAIL).orElse("")).build();

if(!this.getSubject().equals(userInfo.getString(OpenIdConstant.SUBJECT_IDENTIFIER))) {
throw new IllegalStateException("UserInfo Response is invalid as sub claim must match with the sub Claim in the ID Token");
}

return userInfo;
}

@Override
public OpenIdClaims getClaims() {
return new JsonClaims(getClaimsJson());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Payara Foundation and/or its affiliates. All rights reserved.
* Copyright (c) 2021 Payara Foundation and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
Expand Down Expand Up @@ -240,4 +240,11 @@
* @return
*/
int tokenMinValidity() default 10 * 1000;

/**
* Optional. Indicates to skip the /userinfo endpoint call and get the user information from ID Token.
*
* @return
*/
boolean userClaimsFromIDToken() default false;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Payara Foundation and/or its affiliates. All rights reserved.
* Copyright (c) 2021 Payara Foundation and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
Expand Down Expand Up @@ -227,4 +227,12 @@
* @return
*/
int tokenMinValidity() default 10 * 1000;

/**
* Optional. Indicates to skip the /userinfo endpoint call and get the user information from ID Token.
*
* @return
*/
boolean userClaimsFromIDToken() default false;

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Payara Foundation and/or its affiliates. All rights reserved.
* Copyright (c) 2021 Payara Foundation and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
Expand Down Expand Up @@ -232,6 +232,13 @@
*/
int tokenMinValidity() default 10 * 1000;

/**
* Optional. Indicates to skip the /userinfo endpoint call and get the user information from ID Token.
*
* @return
*/
boolean userClaimsFromIDToken() default false;

/**
* The Microprofile Config key for the provider uri is <code>{@value}</code>
*/
Expand Down Expand Up @@ -359,4 +366,10 @@
* The Microprofile Config key for evaluating EL expressions for every HTTP session is <code>{@value}</code>
*/
String OPENID_MP_SESSION_SCOPED_CONFIGURATION = "payara.security.openid.sessionScopedConfiguration";

/**
* The Microprofile Config key to skip the /userinfo endpoint call
* and get the user information from ID Token is <code>{@value}</code>
*/
String OPENID_MP_USER_CLAIMS_FROM_ID_TOKEN = "payara.security.openid.userClaimsFromIDToken";
}