diff --git a/jans-auth-server/client/src/test/java/io/jans/as/client/client/assertbuilders/RegisterResponseAssertBuilder.java b/jans-auth-server/client/src/test/java/io/jans/as/client/client/assertbuilders/RegisterResponseAssertBuilder.java
index 0b823b2d0d7..9de304dbd8d 100644
--- a/jans-auth-server/client/src/test/java/io/jans/as/client/client/assertbuilders/RegisterResponseAssertBuilder.java
+++ b/jans-auth-server/client/src/test/java/io/jans/as/client/client/assertbuilders/RegisterResponseAssertBuilder.java
@@ -3,6 +3,7 @@
import io.jans.as.client.RegisterResponse;
import io.jans.as.model.common.BackchannelTokenDeliveryMode;
import io.jans.as.model.crypto.signature.AsymmetricSignatureAlgorithm;
+import org.apache.commons.lang3.BooleanUtils;
import static io.jans.as.model.register.RegisterRequestParam.*;
import static org.testng.Assert.*;
@@ -84,7 +85,7 @@ public void check() {
assertTrue(response.getClaims().containsKey(BACKCHANNEL_AUTHENTICATION_REQUEST_SIGNING_ALG.toString()));
assertEquals(response.getClaims().get(BACKCHANNEL_AUTHENTICATION_REQUEST_SIGNING_ALG.toString()), backchannelRequestSigningAlgorithm.getValue());
}
- if (backchannelUserCodeParameter != null) {
+ if (BooleanUtils.isTrue(backchannelUserCodeParameter)) {
assertTrue(response.getClaims().containsKey(BACKCHANNEL_USER_CODE_PARAMETER.toString()));
assertEquals(response.getClaims().get(BACKCHANNEL_USER_CODE_PARAMETER.toString()), String.valueOf(backchannelUserCodeParameter));
}
diff --git a/jans-auth-server/model/pom.xml b/jans-auth-server/model/pom.xml
index 2641ddf410d..bf5c55833e4 100644
--- a/jans-auth-server/model/pom.xml
+++ b/jans-auth-server/model/pom.xml
@@ -101,7 +101,7 @@
com.fasterxml.jackson.module
- jackson-module-jaxb-annotations
+ jackson-module-jakarta-xmlbind-annotations
commons-codec
diff --git a/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthorizeRestWebServiceImpl.java b/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthorizeRestWebServiceImpl.java
index 8733ae0b1ca..c1e27bc8bcf 100644
--- a/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthorizeRestWebServiceImpl.java
+++ b/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthorizeRestWebServiceImpl.java
@@ -332,23 +332,20 @@ private static boolean canLogWebApplicationException(WebApplicationException e)
private ResponseBuilder authorize(AuthzRequest authzRequest) throws AcrChangedException, SearchException, TokenBindingParseException {
String tokenBindingHeader = authzRequest.getHttpRequest().getHeader("Sec-Token-Binding");
+ boolean isPar = authzRequestService.processPar(authzRequest);
+
List prompts = Prompt.fromString(authzRequest.getPrompt(), " ");
final List responseTypes = authzRequest.getResponseTypeList();
SessionId sessionUser = identity.getSessionId();
User user = sessionIdService.getUser(sessionUser);
- boolean isPar = authzRequestService.processPar(authzRequest);
-
- Map customResponseHeaders = Util.jsonObjectArrayStringAsMap(authzRequest.getCustomResponseHeaders());
-
updateSessionForROPC(authzRequest.getHttpRequest(), sessionUser);
Client client = authorizeRestWebServiceValidator.validateClient(authzRequest, isPar);
String deviceAuthzUserCode = deviceAuthorizationService.getUserCodeFromSession(authzRequest.getHttpRequest());
authzRequest.setRedirectUri(authorizeRestWebServiceValidator.validateRedirectUri(client, authzRequest.getRedirectUri(), authzRequest.getState(), deviceAuthzUserCode, authzRequest.getHttpRequest()));
-
authzRequestService.createRedirectUriResponse(authzRequest);
authorizeRestWebServiceValidator.validateAcrs(authzRequest, client);
@@ -357,7 +354,8 @@ private ResponseBuilder authorize(AuthzRequest authzRequest) throws AcrChangedEx
authorizeRestWebServiceValidator.checkSignedRequestRequired(authzRequest);
- authzRequestService.processRequestObject(authzRequest, client, scopes, user);
+ authzRequestService.processRequestObject(authzRequest, client, scopes, user, prompts);
+
validateRequestJwt(authzRequest, isPar, client);
authorizeRestWebServiceValidator.validate(authzRequest, responseTypes, client);
@@ -503,11 +501,7 @@ private ResponseBuilder authorize(AuthzRequest authzRequest) throws AcrChangedEx
ResponseBuilder builder = RedirectUtil.getRedirectResponseBuilder(authzRequest.getRedirectUriResponse().getRedirectUri(), authzRequest.getHttpRequest());
- if (isTrue(appConfiguration.getCustomHeadersWithAuthorizationResponse())) {
- for (Entry entry : customResponseHeaders.entrySet()) {
- builder.header(entry.getKey(), entry.getValue());
- }
- }
+ addCustomHeaders(builder, authzRequest);
runCiba(authzRequest.getAuthReqId(), client, authzRequest.getHttpRequest(), authzRequest.getHttpResponse());
processDeviceAuthorization(deviceAuthzUserCode, user);
@@ -515,6 +509,16 @@ private ResponseBuilder authorize(AuthzRequest authzRequest) throws AcrChangedEx
return builder;
}
+ private void addCustomHeaders(ResponseBuilder builder, AuthzRequest authzRequest) {
+ if (isTrue(appConfiguration.getCustomHeadersWithAuthorizationResponse())) {
+
+ Map customResponseHeaders = Util.jsonObjectArrayStringAsMap(authzRequest.getCustomResponseHeaders());
+ for (Entry entry : customResponseHeaders.entrySet()) {
+ builder.header(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+
private void addResponseParameterScope(AuthzRequest authzRequest, AuthorizationGrant authorizationGrant) {
if (authorizationGrant != null && !appConfiguration.isFapi()) {
authzRequest.setScope(authorizationGrant.checkScopesPolicy(authzRequest.getScope()));
diff --git a/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthzRequestService.java b/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthzRequestService.java
index 26d727794b3..e9001a51de0 100644
--- a/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthzRequestService.java
+++ b/jans-auth-server/server/src/main/java/io/jans/as/server/authorize/ws/rs/AuthzRequestService.java
@@ -7,6 +7,7 @@
import io.jans.as.common.util.RedirectUri;
import io.jans.as.common.util.CommonUtils;
import io.jans.as.model.authorize.AuthorizeErrorResponseType;
+import io.jans.as.model.common.Prompt;
import io.jans.as.model.common.ResponseMode;
import io.jans.as.model.config.WebKeysConfiguration;
import io.jans.as.model.configuration.AppConfiguration;
@@ -25,7 +26,6 @@
import io.jans.as.model.jwt.JwtHeader;
import io.jans.as.model.jwt.JwtHeaderName;
import io.jans.as.model.token.JsonWebResponse;
-import io.jans.as.model.util.JwtUtil;
import io.jans.as.model.util.Util;
import io.jans.as.persistence.model.Par;
import io.jans.as.server.model.audit.Action;
@@ -56,6 +56,7 @@
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.util.HashMap;
+import java.util.List;
import java.util.Set;
import static io.jans.as.model.util.StringUtils.implode;
@@ -68,6 +69,8 @@
@Named
public class AuthzRequestService {
+ public static final String INVALID_JWT_AUTHORIZATION_REQUEST = "Invalid JWT authorization request";
+
@Inject
private Logger log;
@@ -155,100 +158,119 @@ public boolean processPar(AuthzRequest authzRequest) {
}
@SuppressWarnings("java:S3776")
- public void processRequestObject(AuthzRequest authzRequest, Client client, Set scopes, User user) {
- JwtAuthorizationRequest jwtRequest = null;
-
- if (StringUtils.isBlank(authzRequest.getRequest()) && StringUtils.isBlank(authzRequest.getRequestUri())) {
- return;
- }
+ public void processRequestObject(AuthzRequest authzRequest, Client client, Set scopes, User user, List prompts) {
+ final RedirectUriResponse redirectUriResponse = authzRequest.getRedirectUriResponse();
- RedirectUriResponse redirectUriResponse = authzRequest.getRedirectUriResponse();
- try {
- jwtRequest = JwtAuthorizationRequest.createJwtRequest(authzRequest.getRequest(), authzRequest.getRequestUri(), client, redirectUriResponse, cryptoProvider, appConfiguration);
+ JwtAuthorizationRequest jwtRequest = null;
+ if (StringUtils.isNotBlank(authzRequest.getRequest()) || StringUtils.isNotBlank(authzRequest.getRequestUri())) {
+ try {
+ jwtRequest = JwtAuthorizationRequest.createJwtRequest(authzRequest.getRequest(), authzRequest.getRequestUri(), client, redirectUriResponse, cryptoProvider, appConfiguration);
- if (jwtRequest == null) {
- throw authorizeRestWebServiceValidator.createInvalidJwtRequestException(redirectUriResponse, "Failed to parse jwt.");
- }
- authzRequest.setJwtRequest(jwtRequest);
+ if (jwtRequest == null) {
+ throw authorizeRestWebServiceValidator.createInvalidJwtRequestException(redirectUriResponse, "Failed to parse jwt.");
+ }
+ authzRequest.setJwtRequest(jwtRequest);
- if (StringUtils.isNotBlank(jwtRequest.getState())) {
- authzRequest.setState(jwtRequest.getState());
- redirectUriResponse.setState(authzRequest.getState());
- }
- if (appConfiguration.isFapi() && StringUtils.isBlank(jwtRequest.getState())) {
- authzRequest.setState(""); // #1250 - FAPI : discard state if in JWT we don't have state
- redirectUriResponse.setState("");
- }
+ if (StringUtils.isNotBlank(jwtRequest.getState())) {
+ authzRequest.setState(jwtRequest.getState());
+ redirectUriResponse.setState(authzRequest.getState());
+ }
+ if (appConfiguration.isFapi() && StringUtils.isBlank(jwtRequest.getState())) {
+ authzRequest.setState(""); // #1250 - FAPI : discard state if in JWT we don't have state
+ redirectUriResponse.setState("");
+ }
- if (jwtRequest.getRedirectUri() != null) {
- redirectUriResponse.getRedirectUri().setBaseRedirectUri(jwtRequest.getRedirectUri());
- }
+ if (jwtRequest.getRedirectUri() != null) {
+ redirectUriResponse.getRedirectUri().setBaseRedirectUri(jwtRequest.getRedirectUri());
+ }
- SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.fromString(jwtRequest.getAlgorithm());
- if (Boolean.TRUE.equals(appConfiguration.getForceSignedRequestObject()) && signatureAlgorithm == SignatureAlgorithm.NONE) {
- throw authorizeRestWebServiceValidator.createInvalidJwtRequestException(redirectUriResponse, "A signed request object is required");
- }
+ SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.fromString(jwtRequest.getAlgorithm());
+ if (Boolean.TRUE.equals(appConfiguration.getForceSignedRequestObject()) && signatureAlgorithm == SignatureAlgorithm.NONE) {
+ throw authorizeRestWebServiceValidator.createInvalidJwtRequestException(redirectUriResponse, "A signed request object is required");
+ }
- // JWT wins
- if (!jwtRequest.getScopes().isEmpty()) {
- if (!scopes.contains("openid")) { // spec: Even if a scope parameter is present in the Request Object value, a scope parameter MUST always be passed using the OAuth 2.0 request syntax containing the openid scope value
- throw new WebApplicationException(Response
- .status(Response.Status.BAD_REQUEST)
- .entity(errorResponseFactory.getErrorAsJson(AuthorizeErrorResponseType.INVALID_SCOPE, authzRequest.getState(), "scope parameter does not contain openid value which is required."))
- .build());
+ // JWT wins
+ if (!jwtRequest.getScopes().isEmpty()) {
+ if (!scopes.contains("openid")) { // spec: Even if a scope parameter is present in the Request Object value, a scope parameter MUST always be passed using the OAuth 2.0 request syntax containing the openid scope value
+ throw new WebApplicationException(Response
+ .status(Response.Status.BAD_REQUEST)
+ .entity(errorResponseFactory.getErrorAsJson(AuthorizeErrorResponseType.INVALID_SCOPE, authzRequest.getState(), "scope parameter does not contain openid value which is required."))
+ .build());
+ }
+
+ scopes.clear();
+ scopes.addAll(scopeChecker.checkScopesPolicy(client, Lists.newArrayList(jwtRequest.getScopes())));
+ }
+ if (jwtRequest.getRedirectUri() != null && !jwtRequest.getRedirectUri().equals(authzRequest.getRedirectUri())) {
+ throw authorizeRestWebServiceValidator.createInvalidJwtRequestException(redirectUriResponse, "The redirect_uri parameter is not the same in the JWT");
+ }
+ if (StringUtils.isNotBlank(jwtRequest.getNonce())) {
+ authzRequest.setNonce(jwtRequest.getNonce());
+ }
+ if (StringUtils.isNotBlank(jwtRequest.getCodeChallenge())) {
+ authzRequest.setCodeChallenge(jwtRequest.getCodeChallenge());
+ }
+ if (StringUtils.isNotBlank(jwtRequest.getCodeChallengeMethod())) {
+ authzRequest.setCodeChallengeMethod(jwtRequest.getCodeChallengeMethod());
+ }
+ if (jwtRequest.getDisplay() != null && StringUtils.isNotBlank(jwtRequest.getDisplay().getParamName())) {
+ authzRequest.setDisplay(jwtRequest.getDisplay().getParamName());
+ }
+ if (!jwtRequest.getPrompts().isEmpty()) {
+ prompts.clear();
+ prompts.addAll(Lists.newArrayList(jwtRequest.getPrompts()));
+ authzRequest.setPrompt(implode(prompts, " "));
+ }
+ if (jwtRequest.getResponseMode() != null) {
+ authzRequest.setResponseMode(jwtRequest.getResponseMode().getValue());
+ redirectUriResponse.getRedirectUri().setResponseMode(jwtRequest.getResponseMode());
}
- Set checkedScopes = scopeChecker.checkScopesPolicy(client, Lists.newArrayList(jwtRequest.getScopes()));
- scopes.clear();
- scopes.addAll(checkedScopes);
- }
- if (jwtRequest.getRedirectUri() != null && !jwtRequest.getRedirectUri().equals(authzRequest.getRedirectUri())) {
- throw authorizeRestWebServiceValidator.createInvalidJwtRequestException(redirectUriResponse, "The redirect_uri parameter is not the same in the JWT");
- }
- if (StringUtils.isNotBlank(jwtRequest.getNonce())) {
- authzRequest.setNonce(jwtRequest.getNonce());
- }
- if (StringUtils.isNotBlank(jwtRequest.getCodeChallenge())) {
- authzRequest.setCodeChallenge(jwtRequest.getCodeChallenge());
- }
- if (StringUtils.isNotBlank(jwtRequest.getCodeChallengeMethod())) {
- authzRequest.setCodeChallengeMethod(jwtRequest.getCodeChallengeMethod());
- }
- if (jwtRequest.getDisplay() != null && StringUtils.isNotBlank(jwtRequest.getDisplay().getParamName())) {
- authzRequest.setDisplay(jwtRequest.getDisplay().getParamName());
- }
- if (!jwtRequest.getPrompts().isEmpty()) {
- authzRequest.setPrompt(implode(jwtRequest.getPrompts(), " "));
- }
- if (jwtRequest.getResponseMode() != null) {
- authzRequest.setResponseMode(jwtRequest.getResponseMode().getValue());
- redirectUriResponse.getRedirectUri().setResponseMode(jwtRequest.getResponseMode());
+ checkIdTokenMember(authzRequest, redirectUriResponse, user, jwtRequest);
+ requestParameterService.getCustomParameters(jwtRequest, authzRequest.getCustomParameters());
+ } catch (WebApplicationException e) {
+ JsonWebResponse jwr = parseRequestToJwr(authzRequest.getRequest());
+ if (jwr != null) {
+ String checkForAlg = jwr.getClaims().getClaimAsString("alg"); // to handle Jans Issue#310
+ if ("none".equals(checkForAlg)) {
+ throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST)
+ .entity(errorResponseFactory.getErrorAsJson(
+ AuthorizeErrorResponseType.INVALID_REQUEST_OBJECT, "",
+ "The None algorithm in nested JWT is not allowed for FAPI"))
+ .type(MediaType.APPLICATION_JSON_TYPE).build());
+ }
+ ResponseMode responseMode = ResponseMode.getByValue(jwr.getClaims().getClaimAsString("response_mode"));
+ if (responseMode == ResponseMode.JWT) {
+ authzRequest.setResponseMode(responseMode.getValue());
+ redirectUriResponse.getRedirectUri().setResponseMode(ResponseMode.JWT);
+ fillRedirectUriResponseforJARM(redirectUriResponse, jwr, client);
+ if (appConfiguration.isFapi()) {
+ authorizeRestWebServiceValidator.throwInvalidJwtRequestExceptionAsJwtMode(
+ redirectUriResponse, INVALID_JWT_AUTHORIZATION_REQUEST,
+ jwr.getClaims().getClaimAsString("state"), authzRequest.getHttpRequest());
+ }
+ }
+ }
+ throw e;
+ } catch (Exception e) {
+ log.error("Invalid JWT authorization request. Message : " + e.getMessage(), e);
+ throw authorizeRestWebServiceValidator.createInvalidJwtRequestException(redirectUriResponse, INVALID_JWT_AUTHORIZATION_REQUEST);
}
-
- checkIdTokenMember(authzRequest, redirectUriResponse, user, jwtRequest);
- requestParameterService.getCustomParameters(jwtRequest, authzRequest.getCustomParameters());
- } catch (WebApplicationException e) {
- JsonWebResponse jwr = parseRequestToJwr(authzRequest.getRequest());
- handleJwr(authzRequest, client, redirectUriResponse, jwr);
- throw e;
- } catch (Exception e) {
- log.error("Invalid JWT authorization request. Message : " + e.getMessage(), e);
- throw authorizeRestWebServiceValidator.createInvalidJwtRequestException(redirectUriResponse, "Invalid JWT authorization request");
}
-
// JARM
Set jwtResponseModes = Sets.newHashSet(ResponseMode.QUERY_JWT, ResponseMode.FRAGMENT_JWT, ResponseMode.JWT, ResponseMode.FORM_POST_JWT);
if (jwtResponseModes.contains(authzRequest.getResponseModeEnum())) {
JsonWebResponse jwe = parseRequestToJwr(authzRequest.getRequest());
fillRedirectUriResponseforJARM(redirectUriResponse, jwe, client);
}
-
// Validate JWT request object after JARM check, because we want to return errors well formatted (JSON/JWT).
- authorizeRestWebServiceValidator.validateJwtRequest(authzRequest.getClientId(), authzRequest.getState(), authzRequest.getHttpRequest(), authzRequest.getResponseTypeList(), redirectUriResponse, jwtRequest);
+ if (jwtRequest != null) {
+ authorizeRestWebServiceValidator.validateJwtRequest(authzRequest.getClientId(), authzRequest.getState(), authzRequest.getHttpRequest(), authzRequest.getResponseTypeList(), redirectUriResponse, jwtRequest);
+ }
}
- private void handleJwr(AuthzRequest authzRequest, Client client, RedirectUriResponse redirectUriResponse, JsonWebResponse jwr) {
+ public void handleJwr(AuthzRequest authzRequest, Client client, RedirectUriResponse redirectUriResponse, JsonWebResponse jwr) {
if (jwr == null) {
return;
}
@@ -268,13 +290,13 @@ private void handleJwr(AuthzRequest authzRequest, Client client, RedirectUriResp
fillRedirectUriResponseforJARM(redirectUriResponse, jwr, client);
if (appConfiguration.isFapi()) {
authorizeRestWebServiceValidator.throwInvalidJwtRequestExceptionAsJwtMode(
- redirectUriResponse, "Invalid JWT authorization request",
+ redirectUriResponse, INVALID_JWT_AUTHORIZATION_REQUEST,
jwr.getClaims().getClaimAsString("state"), authzRequest.getHttpRequest());
}
}
}
- private void checkIdTokenMember(AuthzRequest authzRequest, RedirectUriResponse redirectUriResponse, User user, JwtAuthorizationRequest jwtRequest) {
+ public void checkIdTokenMember(AuthzRequest authzRequest, RedirectUriResponse redirectUriResponse, User user, JwtAuthorizationRequest jwtRequest) {
final IdTokenMember idTokenMember = jwtRequest.getIdTokenMember();
if (idTokenMember == null) {
return;
@@ -330,7 +352,7 @@ public JsonWebResponse parseRequestToJwr(String request) {
}
}
- private void fillRedirectUriResponseforJARM(RedirectUriResponse redirectUriResponse, JsonWebResponse jwr, Client client) {
+ public void fillRedirectUriResponseforJARM(RedirectUriResponse redirectUriResponse, JsonWebResponse jwr, Client client) {
try {
if (jwr != null) {
String tempRedirectUri = jwr.getClaims().getClaimAsString("redirect_uri");
diff --git a/jans-bom/pom.xml b/jans-bom/pom.xml
index 9cd56a00733..d66f7da2e62 100644
--- a/jans-bom/pom.xml
+++ b/jans-bom/pom.xml
@@ -518,8 +518,8 @@
${jackson.version}
- com.fasterxml.jackson.module
- jackson-module-jaxb-annotations
+ com.fasterxml.jackson.module
+ jackson-module-jakarta-xmlbind-annotations
${jackson.version}