fix OIDC client

This commit is contained in:
2022-12-09 11:02:21 +01:00
parent c73c172abe
commit 27c6ab5630
14 changed files with 187 additions and 11 deletions
@@ -120,6 +120,16 @@ public class OidcAuthorizationManager {
return authorizationCode;
}
/**
*
* @param authorizationCode
* @return
*/
public OidcAuthorizationCode setCode(OidcAuthorizationCode authorizationCode) {
authorizationCodes.put(authorizationCode.getCode(), authorizationCode);
return authorizationCode;
}
/**
* Gets the code.
*
@@ -144,6 +144,7 @@ public class OidcTokenManager implements SmartInitializingSingleton {
*/
public OidcToken createToken(OidcClient client, Long userId, String refreshToken) {
OidcToken token = new OidcToken();
token.setClient(client.getId());
token.setUserId(userId);
token.setAccessToken(RandomStringUtils.random(ACCESS_TOKEN_LENGTH, true, true));
if (StringUtils.hasText(refreshToken)) {
@@ -166,8 +167,8 @@ public class OidcTokenManager implements SmartInitializingSingleton {
* @return the oidc token
* @throws JOSEException the JOSE exception
*/
public OidcToken createTokenWithIdToken(OidcClient client, Long userId, String nonce, Set<String> scopes,
String issuer, String sid) throws JOSEException {
public OidcToken createTokenWithIdToken(OidcClient client, Long userId, String alias, String nonce,
Set<String> scopes, String issuer, String sid) throws JOSEException {
User user = userManager.get(userId);
Assert.notNull(user, "User does not exist!");
@@ -175,10 +176,11 @@ public class OidcTokenManager implements SmartInitializingSingleton {
client.getAuthorizationGrantTypes().contains(OidcAuthorizationGrantType.refresh_token));
token.setUserId(user.getId());
token.setAlias(alias);
token.setAccessToken(RandomStringUtils.random(ACCESS_TOKEN_LENGTH, true, true));
token.setExpiresIn(client.getTokenLifetime());
Builder claimsSetBuilder = createUserClaims(client, user);
Builder claimsSetBuilder = createUserClaims(client, user, alias);
claimsSetBuilder.issuer(issuer);
claimsSetBuilder.audience(client.getClientId());
@@ -219,13 +221,17 @@ public class OidcTokenManager implements SmartInitializingSingleton {
* @param user the user
* @return the builder
*/
public Builder createUserClaims(OidcClient client, User user) {
public Builder createUserClaims(OidcClient client, User user, String alias) {
Builder claimsSetBuilder = new Builder();
claimsSetBuilder.subject(String.valueOf(user.getId()));
String username = user.getUsername();
if (StringUtils.hasText(alias) && client.isAliasAllowed()) {
username = alias;
}
claimsSetBuilder.claim("name", username);
claimsSetBuilder.claim("username", username);
claimsSetBuilder.claim("preferred_username", username);
@@ -26,6 +26,7 @@ public class OidcAuthorizationCode {
private final Long userId;
private final String nonce;
private String springSession;
private String alias;
/**
* Instantiates a new oidc authorization code.
@@ -127,4 +128,18 @@ public class OidcAuthorizationCode {
this.springSession = springSession;
}
/**
* @return the alias
*/
public String getAlias() {
return alias;
}
/**
* @param alias the alias to set
*/
public void setAlias(String alias) {
this.alias = alias;
}
}
@@ -30,6 +30,7 @@ import com.google.common.collect.Sets;
import de.bstly.we.businesslogic.PermissionManager;
import de.bstly.we.businesslogic.Permissions;
import de.bstly.we.businesslogic.UserAliasManager;
import de.bstly.we.oidc.businesslogic.OidcAuthorizationManager;
import de.bstly.we.oidc.businesslogic.OidcClientManager;
import de.bstly.we.oidc.businesslogic.exception.InvalidAuthorizationRequestException;
@@ -56,6 +57,8 @@ public class OidcAuthorizationController {
private OidcClientManager oidcClientManager;
@Autowired
private OidcAuthorizationManager oidcAuthorizationManager;
@Autowired
private UserAliasManager userAliasManager;
@Value("${oidcAuthorizationFormUrl:/oidc/authorize/form}")
private String authorizationFormUrl;
@@ -169,16 +172,30 @@ public class OidcAuthorizationController {
"code does not match user", state);
}
if (StringUtils.hasText(principal.getAlias())) {
if (!userAliasManager.hasAlias(principal.getUserId(), principal.getAlias())) {
throw new InvalidAuthorizationRequestException(redirectUri,
OidcAuthorizationErrorCode.ACCOUNT_SELECTION_REQUIRED, "alias does not match user", state);
}
authorizationCode.setAlias(principal.getAlias());
oidcAuthorizationManager.setCode(authorizationCode);
}
oidcAuthorizationManager.authorize(client.getId(), principal.getUserId(), scopes);
} else {
if (client.isAuthorize()
&& !oidcAuthorizationManager.isAuthorized(client.getId(), principal.getUserId(), scopes)
|| prompts.contains("consent")) {
|| prompts.contains("consent")
|| client.isAliasAllowed() && !userAliasManager.getAllByTarget(principal.getUserId()).isEmpty()) {
uriBuilder = UriComponentsBuilder.fromUriString(authorizationFormUrl);
uriBuilder.queryParam("client_id", clientId);
uriBuilder.queryParam("response_type", responseType);
uriBuilder.queryParam("redirect_uri", redirectUri);
uriBuilder.queryParam("scope", scope);
uriBuilder.queryParam("authorize", client.isAuthorize()
&& !oidcAuthorizationManager.isAuthorized(client.getId(), principal.getUserId(), scopes));
uriBuilder.queryParam("alias",
client.isAliasAllowed() && !userAliasManager.getAllByTarget(principal.getUserId()).isEmpty());
if (StringUtils.hasText(nonce)) {
uriBuilder.queryParam("nonce", nonce);
@@ -176,7 +176,7 @@ public class OidcTokenController {
try {
String sid = oidcSessionManager.createSid();
token = oidcTokenManager.createTokenWithIdToken(client, authorizationCode.getUserId(),
authorizationCode.getNonce(), scopes, issuer, sid);
authorizationCode.getAlias(), authorizationCode.getNonce(), scopes, issuer, sid);
oidcSessionManager.createSession(client.getId(), authorizationCode.getUserId(), token.getIdToken(), sid,
authorizationCode.getSpringSession());
} catch (JOSEException e) {
@@ -23,6 +23,7 @@ import de.bstly.we.oidc.businesslogic.OidcClientManager;
import de.bstly.we.oidc.businesslogic.OidcTokenManager;
import de.bstly.we.oidc.model.OidcClient;
import de.bstly.we.oidc.model.OidcToken;
import de.bstly.we.security.model.LocalUserDetails;
/**
* The Class OidcUserInfoController.
@@ -50,6 +51,13 @@ public class OidcUserInfoController extends BaseController {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
Long userId = getCurrentUserId();
String alias = null;
if (auth.getPrincipal() != null && auth.getPrincipal() instanceof LocalUserDetails) {
alias = ((LocalUserDetails) auth.getPrincipal()).getAlias();
}
OidcClient client = null;
if (!auth.isAuthenticated()) {
if (authorizationHeader == null) {
@@ -63,6 +71,7 @@ public class OidcUserInfoController extends BaseController {
throw new EntityResponseStatusException(HttpStatus.UNAUTHORIZED);
}
userId = token.getUserId();
alias = token.getAlias();
client = oidcClientManager.get(token.getClient());
}
@@ -72,7 +81,7 @@ public class OidcUserInfoController extends BaseController {
throw new EntityResponseStatusException(HttpStatus.CONFLICT);
}
Builder claimsSetBuilder = oidcTokenManager.createUserClaims(client, user);
Builder claimsSetBuilder = oidcTokenManager.createUserClaims(client, user, alias);
throw new EntityResponseStatusException(claimsSetBuilder.build().toJSONObject(), HttpStatus.OK);
@@ -71,6 +71,8 @@ public class OidcClient {
private boolean backchannelLogoutSessionRequired;
@Column(name = "authorize", columnDefinition = "boolean default false")
private boolean authorize;
@Column(name = "alias_allowed", columnDefinition = "boolean default false")
private boolean aliasAllowed;
@Column(name = "always_permitted", columnDefinition = "boolean default false")
private boolean alwaysPermitted;
@Column(name = "category")
@@ -348,6 +350,20 @@ public class OidcClient {
this.authorize = authorize;
}
/**
* @return the aliasAllowed
*/
public boolean isAliasAllowed() {
return aliasAllowed;
}
/**
* @param aliasAllowed the aliasAllowed to set
*/
public void setAliasAllowed(boolean aliasAllowed) {
this.aliasAllowed = aliasAllowed;
}
/**
* Checks if is always permitted.
*
@@ -34,6 +34,8 @@ public class OidcToken {
private Instant created;
@Column(name = "user_id")
private Long userId;
@Column(name = "alias")
private String alias;
@Column(name = "client_id")
private Long client;
@Column(name = "access_token")
@@ -103,6 +105,20 @@ public class OidcToken {
this.userId = userId;
}
/**
* @return the alias
*/
public String getAlias() {
return alias;
}
/**
* @param alias the alias to set
*/
public void setAlias(String alias) {
this.alias = alias;
}
/**
* Gets the client.
*