Skip to content

Commit

Permalink
feat: add feature to include custom-claims in user-info endpoint of a…
Browse files Browse the repository at this point in the history
…dmin-ui plugin #2969
  • Loading branch information
duttarnab committed Nov 14, 2022
1 parent 7f93bca commit 51f87ab
Show file tree
Hide file tree
Showing 4 changed files with 371 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ public void setClaims(Map<String, Object> claims) {
this.claims = claims;
}

public void addClaims(String key, Object value) {
this.claims.put(key, value);
}

public String getJwtUserInfo() {
return jwtUserInfo;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,26 @@ public TokenResponse getApiProtectionToken(String userInfoJwt) throws Applicatio
}
}

public Map<String, Object> introspectToken(String accessToken) {
log.info("Token introspection from auth-server.");
AUIConfiguration auiConfiguration = auiConfigurationService.getAUIConfiguration();
Invocation.Builder request = ClientFactory.instance().getClientBuilder(auiConfiguration.getAuthServerIntrospectionEndpoint());
request.header("Authorization", "Bearer " + accessToken);

MultivaluedMap<String, String> body = new MultivaluedHashMap<>();
body.putSingle("token", accessToken);

Response response = request.post(Entity.form(body));

log.info("Introspection response status code: {}", response.getStatus());

if (response.getStatus() == 200) {
Map<String, Object> entity = response.readEntity(Map.class);
log.info("Introspection response entity: {}", entity);
return entity;
}
return null;
}
public UserInfoResponse getUserInfo(UserInfoRequest userInfoRequest) throws ApplicationException {
try {
log.debug("Getting User-Info from auth-server: {}", userInfoRequest.getAccessToken());
Expand All @@ -151,6 +171,8 @@ public UserInfoResponse getUserInfo(UserInfoRequest userInfoRequest) throws Appl
accessToken = tokenResponse.getAccessToken();
}
log.debug("Access Token : {}", accessToken);
Map<String, Object> introspectionResponse = introspectToken(accessToken);

MultivaluedMap<String, String> body = new MultivaluedHashMap<>();
body.putSingle("access_token", accessToken);

Expand All @@ -172,9 +194,11 @@ public UserInfoResponse getUserInfo(UserInfoRequest userInfoRequest) throws Appl
UserInfoResponse userInfoResponse = new UserInfoResponse();
userInfoResponse.setClaims(getClaims(jwtUserInfo));
userInfoResponse.setJwtUserInfo(entity);
if(introspectionResponse.get("customClaims") != null) {
userInfoResponse.addClaims("customClaims", introspectionResponse.get("customClaims"));
}

log.debug("User-Info response userInfoResponse: {}", userInfoResponse);

return userInfoResponse;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.
# Copyright (c) 2019, Janssen
#
#

from io.jans.model.custom.script.type.introspection import IntrospectionType
from io.jans.as.server.model.common import AuthorizationGrantList
from io.jans.as.server.service import SessionIdService
from io.jans.service.cdi.util import CdiUtil
from java.lang import String

class Introspection(IntrospectionType):
def __init__(self, currentTimeMillis):
self.currentTimeMillis = currentTimeMillis

def init(self, customScript, configurationAttributes):
print "Github. Introspection script. Initializing ..."
print "Github. Introspection script. Initialized successfully"

return True

def destroy(self, configurationAttributes):
print "Github. Introspection script. Destroying ..."
print "Github. Introspection script. Destroyed successfully"
return True

def getApiVersion(self):
return 11

# Returns boolean, true - apply introspection method, false - ignore it.
# This method is called after introspection response is ready. This method can modify introspection response.
# Note :
# responseAsJsonObject - is org.codehaus.jettison.json.JSONObject, you can use any method to manipulate json
# context is reference of io.jans.as.service.external.context.ExternalIntrospectionContext (in https://github.com/JanssenFederation/oxauth project, )
def modifyResponse(self, responseAsJsonObject, context):
print "Github. Checking for saved parameters in session ..."
try:
token = context.getHttpRequest().getParameter("token")
if token is None:
print "Github. Introspection. There is no token in request"
return True

authorizationGrantList = CdiUtil.bean(AuthorizationGrantList)
authorizationGrant = authorizationGrantList.getAuthorizationGrantByAccessToken(token)
if authorizationGrant is None:
print "Github. Introspection. Failed to load authorization grant by token"
return False

# Put user_id into response
responseAsJsonObject.accumulate("user_id", authorizationGrant.getUser().getUserId())

# Put custom parameters into response
sessionDn = authorizationGrant.getSessionDn();
print "sessionDn '%s'" % sessionDn
if sessionDn is None:
print "There is no session"
return True

sessionIdService = CdiUtil.bean(SessionIdService)
session = sessionIdService.getSessionByDn(sessionDn, False)
if sessionDn is None:
print "Github. Introspection. Failed to load session '%s'" % sessionDn
return False

# Return session_id
responseAsJsonObject.accumulate("session_id", sessionDn)

sessionAttributes = session.getSessionAttributes()
if sessionAttributes is None:
print "There is no session attributes"
return True

# Append custom claims
customClaims = {}

if sessionAttributes.containsKey("gihub_username"):
customClaims["gihub_username"] = sessionAttributes.get("gihub_username")
if sessionAttributes.containsKey("gihub_access_token"):
customClaims["gihub_access_token"] = sessionAttributes.get("gihub_access_token")

responseAsJsonObject.accumulate("customClaims", customClaims)
except Exception as e:
print "Exception occured. Unable to resolve role/scope mapping."
print e

return True

Loading

0 comments on commit 51f87ab

Please sign in to comment.