-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Link internal OIDC ID token and UserInfo when working with GitHub and other OAuth2 providers #22030
Comments
/cc @pedroigor |
Well no, I only want to be allowed to use the |
The whole UserInfo would be 3 or so simple properties. I can imagine how we can put it as the whole, but I'm not sure it would be worth trying to introduce some extra interfaces allowing users to intercept the faked ID token creation :-), IMHO it would not be worth it in order to do some extra optimization - given the current cache approach works fine |
Well, I don't want the But I do need to be able to use it as a source for what's missing in the IdToken and in the JWT. If you're going to create a fake JWT IdToken (and I think that's a fine thing to have done) then at least let me derive what to add to it. Ideally I'd at least be able to set the @OidcUserInfoMapper
public void mapIt(OidcTenantConfig tenantConfig, JwtClaimsBuilder builder, UserInfo info) {
// only do this for github and facebook
if("github".equals(tenantConfig.tenantId.get())
|| "facebook".equals(tenantConfig.tenantId.get())) {
JsonValue id = (JsonValue) userInfo.get("id");
String idString;
switch(id.getValueType()) {
case NUMBER:
idString = Long.toString(((JsonNumber)id).longValue());
break;
case STRING:
idString = ((JsonString)id).getString();
break;
default:
// bail out
throw new RuntimeException("Don't know how to handle userinfo id: "+id);
}
builder.claim(Claims.upn.name(), idString);
if("github".equals(tenantConfig.tenantId.get())) {
builder.claim(Claims.full_name, userInfo.getString("name"));
builder.claim(Claims.preferred_username, userInfo.getString("login"));
}
if("facebook".equals(tenantConfig.tenantId.get())) {
builder.claim(Claims.given_name, userInfo.getString("first_name"));
builder.claim(Claims.family_name, userInfo.getString("last_name"));
builder.claim(Claims.email, userInfo.getString("email"));
}
}
} This allows users to have a single endpoint for all oidc callbacks, and will only leave a single special-case for github because we need the access token to obtain the user's email via another endpoint. Well, I guess we could support it here too by making If I can't stick that @ApplicationScoped
public class OidcSecurityAugmentor implements SecurityIdentityAugmentor {
@Override
public Uni<SecurityIdentity> augment(SecurityIdentity identity, AuthenticationRequestContext context) {
if(identity.isAnonymous())
return Uni.createFrom().item(identity);
try {
DefaultJWTCallerPrincipal oldPrincipal = (DefaultJWTCallerPrincipal) identity.getPrincipal();
// only do this for github and facebook
if("github".equals(oldPrincipal.getIssuer())
|| "facebook".equals(oldPrincipal.getIssuer())) {
String rawToken = oldPrincipal.getClaim(Claims.raw_token);
JwtClaims claims;
claims = new JwtClaims();
for (String claim : oldPrincipal.getClaimNames()) {
claims.setClaim(claim, oldPrincipal.getClaim(claim));
}
UserInfo userInfo = identity.getAttribute(OidcUtils.USER_INFO_ATTRIBUTE);
JsonValue id = (JsonValue) userInfo.get("id");
String idString;
switch(id.getValueType()) {
case NUMBER:
idString = Long.toString(((JsonNumber)id).longValue());
break;
case STRING:
idString = ((JsonString)id).getString();
break;
default:
// bail out
throw new RuntimeException("Don't know how to handle userinfo id: "+id);
}
claims.setClaim(Claims.upn.name(), idString);
QuarkusSecurityIdentity newIdentity = QuarkusSecurityIdentity.builder(identity).setPrincipal(new DefaultJWTCallerPrincipal(rawToken, "JWT", claims)).build();
return Uni.createFrom().item(newIdentity);
} else {
return Uni.createFrom().item(identity);
}
}catch(Throwable t) {
t.printStackTrace();
throw t;
}
}
} And this is crazy because it forces me to hang on to the |
@FroMage I'm sorry that you want it gone but it will stay injected in the faked token, I've explained why here: Even injecting it will still be a hack on to of another hack - I do all I can to help you have a simpler integration code. |
@sberyozkin won't call to UserInfo require a call back to github ? that seems wasteful. Github isn't like a small irrelevant service - why not add some relevant user info into that fake generated id anyhow and avoid users to do custom stuff just for github ? |
@maxandersen I've missed your comment, sorry. |
Description
Right now, when GitHub or other non-OIDC compliant provider is used which returns no ID token, Quarkus OIDC will generate an internal empty ID token and will enforce that UserInfo is fetched.
Dealing with UserInfo will be more optimal if it is cached, ex, by the default UserInfo cache. However, it may be reasonable instead to use this internal
IdToken
to retain UserInfo, something @FroMage is interested in - thisIdToken
is faked so we can put any claims there and then it will keep this UserInfo as a cookie value.Implementation ideas
Store
UserInfo
as a complexuserinfo
claim in the internal IdToken.We should probably also encrypt the internal token instead in this case -
UserInfo
may contain more sensitive informationThe text was updated successfully, but these errors were encountered: