diff --git a/jans-auth-server/server/src/main/java/io/jans/as/server/model/common/AbstractAuthorizationGrant.java b/jans-auth-server/server/src/main/java/io/jans/as/server/model/common/AbstractAuthorizationGrant.java index cab786c5796..acd2c448214 100644 --- a/jans-auth-server/server/src/main/java/io/jans/as/server/model/common/AbstractAuthorizationGrant.java +++ b/jans-auth-server/server/src/main/java/io/jans/as/server/model/common/AbstractAuthorizationGrant.java @@ -79,6 +79,7 @@ public abstract class AbstractAuthorizationGrant implements IAuthorizationGrant private String acrValues; private String sessionDn; + private boolean isAuthorizationChallenge; protected final ConcurrentMap txTokens = new ConcurrentHashMap<>(); protected final ConcurrentMap accessTokens = new ConcurrentHashMap<>(); @@ -110,6 +111,15 @@ public void setReferenceId(String referenceId) { this.referenceId = referenceId; } + public boolean isAuthorizationChallenge() { + return isAuthorizationChallenge; + } + + public AbstractAuthorizationGrant setAuthorizationChallenge(boolean authorizationChallenge) { + isAuthorizationChallenge = authorizationChallenge; + return this; + } + public Integer getStatusListIndex() { return statusListIndex; } diff --git a/jans-auth-server/server/src/main/java/io/jans/as/server/token/ws/rs/TokenRestWebServiceImpl.java b/jans-auth-server/server/src/main/java/io/jans/as/server/token/ws/rs/TokenRestWebServiceImpl.java index 95134a34a97..b32651ec9f2 100644 --- a/jans-auth-server/server/src/main/java/io/jans/as/server/token/ws/rs/TokenRestWebServiceImpl.java +++ b/jans-auth-server/server/src/main/java/io/jans/as/server/token/ws/rs/TokenRestWebServiceImpl.java @@ -185,7 +185,7 @@ grantType, code, redirectUri, username, refreshToken, clientId, prepareForLogs(r scope = ServerUtil.urlDecode(scope); // it may be encoded in uma case try { - tokenRestWebServiceValidator.validateParams(grantType, code, redirectUri, refreshToken, auditLog); + tokenRestWebServiceValidator.validateParams(grantType, code, refreshToken, auditLog); GrantType gt = GrantType.fromString(grantType); log.debug("Grant type: '{}'", gt); @@ -212,7 +212,7 @@ grantType, code, redirectUri, username, refreshToken, clientId, prepareForLogs(r executionContext.setAuthzDetails(authzDetails); if (gt == GrantType.AUTHORIZATION_CODE) { - return processAuthorizationCode(code, scope, codeVerifier, sessionIdObj, executionContext); + return processAuthorizationCode(code, scope, codeVerifier, sessionIdObj, redirectUri, executionContext); } else if (gt == GrantType.REFRESH_TOKEN) { return processRefreshTokenGrant(scope, refreshToken, idTokenPreProcessing, executionContext); } else if (gt == GrantType.CLIENT_CREDENTIALS) { @@ -434,7 +434,7 @@ private TokenEntity lockAndRemoveRefreshToken(String refreshTokenCode) { return null; } - private Response processAuthorizationCode(String code, String scope, String codeVerifier, SessionId sessionIdObj, ExecutionContext executionContext) { + private Response processAuthorizationCode(String code, String scope, String codeVerifier, SessionId sessionIdObj, String redirectUri, ExecutionContext executionContext) { Client client = executionContext.getClient(); log.debug("Attempting to find authorizationCodeGrant by clientId: '{}', code: '{}'", client.getClientId(), code); @@ -442,6 +442,11 @@ private Response processAuthorizationCode(String code, String scope, String code executionContext.setGrant(authorizationCodeGrant); log.trace("AuthorizationCodeGrant : '{}'", authorizationCodeGrant); + // validate redirectUri only for Authorization Code Flow. For First-Party App redirect uri is blank. It is perfectly valid case. + if (!authorizationCodeGrant.isAuthorizationChallenge()) { + tokenRestWebServiceValidator.validateRedirectUri(redirectUri, executionContext.getAuditLog()); + } + // if authorization code is not found then code was already used or wrong client provided = remove all grants with this auth code tokenRestWebServiceValidator.validateGrant(authorizationCodeGrant, client, code, executionContext.getAuditLog(), grant -> grantService.removeAllByAuthorizationCode(code)); tokenRestWebServiceValidator.validatePKCE(authorizationCodeGrant, codeVerifier, executionContext.getAuditLog()); diff --git a/jans-core/service/src/main/java/io/jans/model/token/TokenAttributes.java b/jans-core/service/src/main/java/io/jans/model/token/TokenAttributes.java index c5a6961d7b2..621ec7851da 100644 --- a/jans-core/service/src/main/java/io/jans/model/token/TokenAttributes.java +++ b/jans-core/service/src/main/java/io/jans/model/token/TokenAttributes.java @@ -26,6 +26,8 @@ public class TokenAttributes implements Serializable { private String x5cs256; @JsonProperty("online_access") private boolean onlineAccess; + @JsonProperty("authorization_challenge") + private boolean authorizationChallenge; @JsonProperty("attributes") private Map attributes; @JsonProperty("dpopJkt") @@ -35,6 +37,15 @@ public class TokenAttributes implements Serializable { @JsonProperty("statusListIndex") private Integer statusListIndex; + public boolean isAuthorizationChallenge() { + return authorizationChallenge; + } + + public TokenAttributes setAuthorizationChallenge(boolean authorizationChallenge) { + this.authorizationChallenge = authorizationChallenge; + return this; + } + public Integer getStatusListIndex() { return statusListIndex; } @@ -92,6 +103,7 @@ public String toString() { "onlineAccess='" + onlineAccess + '\'' + "dpopJkt='" + dpopJkt + '\'' + "authorizationDetails='" + authorizationDetails + '\'' + + "authorizationChallenge='" + authorizationChallenge + '\'' + '}'; } }