Skip to content
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

feat(jans-auth-server): allow return custom authz params to rp in response #756

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,7 @@

package io.jans.as.client.ws.rs;

import io.jans.as.client.AuthorizationRequest;
import io.jans.as.client.AuthorizationResponse;
import io.jans.as.client.AuthorizeClient;
import io.jans.as.client.BaseTest;
import io.jans.as.client.RegisterClient;
import io.jans.as.client.RegisterRequest;
import io.jans.as.client.RegisterResponse;
import io.jans.as.client.*;
import io.jans.as.model.common.Prompt;
import io.jans.as.model.common.ResponseType;
import io.jans.as.model.register.ApplicationType;
Expand All @@ -21,19 +15,13 @@
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.*;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.*;

/**
* @author Javier Rojas Blum
* @version December 26, 2016
* @version February 2, 2022
*/
public class AuthorizationResponseCustomHeaderTest extends BaseTest {

Expand Down Expand Up @@ -93,6 +81,9 @@ public void requestAuthorizationCustomHeader(
assertTrue(authorizationResponse.getHeaders().containsKey("CustomHeader1"));
assertTrue(authorizationResponse.getHeaders().containsKey("CustomHeader2"));
assertTrue(authorizationResponse.getHeaders().containsKey("CustomHeader3"));
assertTrue(authorizationResponse.getHeaders().get("CustomHeader1").contains("custom_header_value_1"));
assertTrue(authorizationResponse.getHeaders().get("CustomHeader2").contains("custom_header_value_2"));
assertTrue(authorizationResponse.getHeaders().get("CustomHeader3").contains("custom_header_value_3"));
}

@DataProvider(name = "requestAuthorizationCustomHeaderDataProvider")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,11 @@
import java.util.List;
import java.util.UUID;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.*;

/**
* @author Javier Rojas Blum
* @version November 23, 2017
* @version February 2, 2022
*/
public class AuthorizationSupportCustomParams extends BaseTest {

Expand Down Expand Up @@ -68,9 +67,11 @@ public void authorizationSupportCustomParams(

AuthorizationRequest authorizationRequest = new AuthorizationRequest(responseTypes, clientId, scopes, redirectUri, nonce);
authorizationRequest.setState(state);
authorizationRequest.addCustomParameter("customParam1", "value1");
authorizationRequest.addCustomParameter("customParam2", "value2");
authorizationRequest.addCustomParameter("customParam3", "value3");
authorizationRequest.addCustomParameter("customParam1", "value1"); // returnInResponse = false
authorizationRequest.addCustomParameter("customParam2", "value2"); // returnInResponse = false
authorizationRequest.addCustomParameter("customParam3", "value3"); // returnInResponse = false
authorizationRequest.addCustomParameter("customParam4", "value4"); // returnInResponse = true
authorizationRequest.addCustomParameter("customParam5", "value5"); // returnInResponse = true

AuthorizeClient authorizeClient = new AuthorizeClient(authorizationEndpoint);
authorizeClient.setRequest(authorizationRequest);
Expand All @@ -84,6 +85,15 @@ public void authorizationSupportCustomParams(
assertNotNull(authorizationResponse.getIdToken(), "The idToken is null");
assertNotNull(authorizationResponse.getState(), "The state is null");

assertNotNull(authorizationResponse.getCustomParams());
assertFalse(authorizationResponse.getCustomParams().containsKey("customParam1"));
assertFalse(authorizationResponse.getCustomParams().containsKey("customParam2"));
assertFalse(authorizationResponse.getCustomParams().containsKey("customParam3"));
assertTrue(authorizationResponse.getCustomParams().containsKey("customParam4"));
assertTrue(authorizationResponse.getCustomParams().containsKey("customParam5"));
assertEquals(authorizationResponse.getCustomParams().get("customParam4"), "value4");
assertEquals(authorizationResponse.getCustomParams().get("customParam5"), "value5");

// NOTE: After complete successfully this test, check whether the stored session in LDAP has the 3 custom params
// stored in its session attributes list.
}
Expand Down
6 changes: 6 additions & 0 deletions jans-auth-server/client/src/test/resources/testng.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@
</classes>
</test>

<test name="Authorization Support Custom Params" enabled="true">
<classes>
<class name="io.jans.as.client.ws.rs.AuthorizationSupportCustomParams"></class>
</classes>
</test>

<!-- Authorize test -->
<test name="Authorize test (HTTP)" enabled="true">
<classes>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
* @author Javier Rojas Blum
* @author Yuriy Zabrovarnyy
* @author Yuriy Movchan
* @version September 30, 2021
* @version February 2, 2022
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class AppConfiguration implements Configuration {
Expand Down Expand Up @@ -239,7 +239,7 @@ public class AppConfiguration implements Configuration {
private Boolean logClientIdOnClientAuthentication;
private Boolean logClientNameOnClientAuthentication;
private Boolean disableJdkLogger = true;
private Set<String> authorizationRequestCustomAllowedParameters;
private Set<AuthorizationRequestCustomParameter> authorizationRequestCustomAllowedParameters;
private Boolean openidScopeBackwardCompatibility = false;
private Boolean disableU2fEndpoint = false;

Expand Down Expand Up @@ -2019,11 +2019,11 @@ public void setExternalLoggerConfiguration(String externalLoggerConfiguration) {
this.externalLoggerConfiguration = externalLoggerConfiguration;
}

public Set<String> getAuthorizationRequestCustomAllowedParameters() {
public Set<AuthorizationRequestCustomParameter> getAuthorizationRequestCustomAllowedParameters() {
return authorizationRequestCustomAllowedParameters;
}

public void setAuthorizationRequestCustomAllowedParameters(Set<String> authorizationRequestCustomAllowedParameters) {
public void setAuthorizationRequestCustomAllowedParameters(Set<AuthorizationRequestCustomParameter> authorizationRequestCustomAllowedParameters) {
this.authorizationRequestCustomAllowedParameters = authorizationRequestCustomAllowedParameters;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text.
*
* Copyright (c) 2020, Janssen Project
*/

package io.jans.as.model.configuration;

import io.jans.util.exception.ConfigurationException;
import org.apache.commons.lang.StringUtils;

/**
* @author Javier Rojas Blum
* @version February 2, 2022
*/
public class AuthorizationRequestCustomParameter {

private String paramName;
private Boolean returnInResponse;

private static final Boolean DEFAULT_RETURN_IN_RESPONSE = false;

public String getParamName() {
if (StringUtils.isEmpty(paramName)) {
throw new ConfigurationException("The param name in a AuthorizationRequestCustomParameter is empty");
}
return paramName;
}

public void setParamName(String paramName) {
this.paramName = paramName;
}

public Boolean getReturnInResponse() {
if (returnInResponse == null) {
returnInResponse = DEFAULT_RETURN_IN_RESPONSE;
}
return returnInResponse;
}

public void setReturnInResponse(Boolean returnInResponse) {
this.returnInResponse = returnInResponse;
}
}
23 changes: 20 additions & 3 deletions jans-auth-server/server/conf/jans-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -359,9 +359,26 @@
"logClientIdOnClientAuthentication": true,
"logClientNameOnClientAuthentication": false,
"authorizationRequestCustomAllowedParameters" : [
"customParam1",
"customParam2",
"customParam3"
{
"paramName": "customParam1",
"returnInResponse": false
},
{
"paramName": "customParam2",
"returnInResponse": false
},
{
"paramName": "customParam3",
"returnInResponse": false
},
{
"paramName": "customParam4",
"returnInResponse": true
},
{
"paramName": "customParam5",
"returnInResponse": true
}
],
"legacyDynamicRegistrationScopeParam": false,
"openidScopeBackwardCompatibility": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
import io.jans.as.model.jwk.JSONWebKeySet;
import io.jans.as.model.jwk.Use;
import io.jans.as.model.jwt.Jwt;
import io.jans.as.model.jwt.JwtClaims;
import io.jans.as.model.jwt.JwtClaimName;
import io.jans.as.model.jwt.JwtClaims;
import io.jans.as.model.token.JsonWebResponse;
import io.jans.as.model.util.JwtUtil;
import io.jans.as.model.util.Util;
Expand Down Expand Up @@ -66,7 +66,6 @@
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.Nullable;
import org.json.JSONObject;
import org.slf4j.Logger;

Expand Down Expand Up @@ -95,7 +94,7 @@
* Implementation for request authorization through REST web services.
*
* @author Javier Rojas Blum
* @version January 24, 2022
* @version February 2, 2022
*/
@Path("/")
public class AuthorizeRestWebServiceImpl implements AuthorizeRestWebService {
Expand Down Expand Up @@ -708,6 +707,10 @@ private Response requestAuthorization(
redirectUriResponse.getRedirectUri().addResponseParameter(AuthorizeResponseParam.ACR_VALUES, acrValuesStr);
}

for (Map.Entry<String, String> customParam : requestParameterService.getCustomParameters(customParameters, true).entrySet()) {
redirectUriResponse.getRedirectUri().addResponseParameter(customParam.getKey(), customParam.getValue());
}

if (sessionUser.getId() == null) {
final SessionId newSessionUser = sessionIdService.generateAuthenticatedSessionId(httpRequest, sessionUser.getUserDn(), prompt);
String newSessionId = newSessionUser.getId();
Expand Down Expand Up @@ -781,7 +784,6 @@ private Response requestAuthorization(
return builder.build();
}

@Nullable
private ResponseMode extractResponseMode(String request) {
final Jwt jwt = Jwt.parseSilently(request);
if (jwt == null) {
Expand All @@ -799,6 +801,7 @@ private void fillRedirectUriResponseforJARM(RedirectUriResponse redirectUriRespo
redirectUriResponse.getRedirectUri().setBaseRedirectUri(URLDecoder.decode(tempRedirectUri, "UTF-8"));
}
}
redirectUriResponse.getRedirectUri().setResponseMode(ResponseMode.JWT);
String clientId = client.getClientId();
redirectUriResponse.getRedirectUri().setIssuer(appConfiguration.getIssuer());
redirectUriResponse.getRedirectUri().setAudience(clientId);
Expand All @@ -812,7 +815,7 @@ private void fillRedirectUriResponseforJARM(RedirectUriResponse redirectUriRespo
if (client.getAttributes().getAuthorizationEncryptedResponseAlg() != null
&& client.getAttributes().getAuthorizationEncryptedResponseEnc() != null) {
if (client.getAttributes().getAuthorizationSignedResponseAlg() != null) { // Signed then Encrypted
// response
// response
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm
.fromString(client.getAttributes().getAuthorizationSignedResponseAlg());

Expand Down Expand Up @@ -860,7 +863,7 @@ private void fillRedirectUriResponseforJARM(RedirectUriResponse redirectUriRespo
log.error(e.getMessage(), e);
}
}

private void validateJwtRequest(String clientId, String state, HttpServletRequest httpRequest, List<ResponseType> responseTypes, RedirectUriResponse redirectUriResponse, JwtAuthorizationRequest jwtRequest) {
try {
jwtRequest.validate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.google.common.collect.Lists;
import io.jans.as.model.authorize.AuthorizeRequestParam;
import io.jans.as.model.configuration.AppConfiguration;
import io.jans.as.model.configuration.AuthorizationRequestCustomParameter;
import io.jans.as.model.util.Util;
import io.jans.as.server.model.authorize.JwtAuthorizationRequest;
import io.jans.model.security.Identity;
Expand All @@ -23,21 +24,15 @@
import javax.inject.Named;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.Map.Entry;
import java.util.Set;

import static org.apache.commons.lang3.BooleanUtils.isTrue;

/**
* @author Yuriy Movchan
* @author Javier Rojas Blum
* @version October 7, 2019
* @version February 2, 2022
*/
@Stateless
@Named
Expand Down Expand Up @@ -85,7 +80,7 @@ private List<String> getAllAllowedParameters() {
}

public Map<String, String> getAllowedParameters(@Nonnull final Map<String, String> requestParameterMap) {
Set<String> authorizationRequestCustomAllowedParameters = appConfiguration.getAuthorizationRequestCustomAllowedParameters();
Set<AuthorizationRequestCustomParameter> authorizationRequestCustomAllowedParameters = appConfiguration.getAuthorizationRequestCustomAllowedParameters();
if (authorizationRequestCustomAllowedParameters == null) {
authorizationRequestCustomAllowedParameters = new HashSet<>(0);
}
Expand All @@ -98,15 +93,21 @@ public Map<String, String> getAllowedParameters(@Nonnull final Map<String, Strin
final List<String> allAllowed = getAllAllowedParameters();
final Set<Map.Entry<String, String>> set = requestParameterMap.entrySet();
for (Map.Entry<String, String> entry : set) {
if (allAllowed.contains(entry.getKey()) || authorizationRequestCustomAllowedParameters.contains(entry.getKey())) {
if (allAllowed.contains(entry.getKey())
|| authorizationRequestCustomAllowedParameters.stream()
.filter(o -> StringUtils.isNotBlank(o.getParamName()) && o.getParamName().equals(entry.getKey())).findFirst().isPresent()) {
result.put(entry.getKey(), entry.getValue());
}
}
return result;
}

public Map<String, String> getCustomParameters(@Nonnull final Map<String, String> requestParameterMap) {
Set<String> authorizationRequestCustomAllowedParameters = appConfiguration.getAuthorizationRequestCustomAllowedParameters();
return getCustomParameters(requestParameterMap, false);
}

public Map<String, String> getCustomParameters(@Nonnull final Map<String, String> requestParameterMap, boolean onlyReturnInResponseParams) {
Set<AuthorizationRequestCustomParameter> authorizationRequestCustomAllowedParameters = appConfiguration.getAuthorizationRequestCustomAllowedParameters();

final Map<String, String> result = new HashMap<>();
if (authorizationRequestCustomAllowedParameters == null) {
Expand All @@ -116,7 +117,15 @@ public Map<String, String> getCustomParameters(@Nonnull final Map<String, String
if (!requestParameterMap.isEmpty()) {
final Set<Map.Entry<String, String>> set = requestParameterMap.entrySet();
for (Map.Entry<String, String> entry : set) {
if (authorizationRequestCustomAllowedParameters.contains(entry.getKey())) {

if (onlyReturnInResponseParams && authorizationRequestCustomAllowedParameters.stream()
.filter(o -> StringUtils.isNotBlank(o.getParamName())
&& o.getParamName().equals(entry.getKey())
&& o.getReturnInResponse()).findFirst().isPresent()) {
result.put(entry.getKey(), entry.getValue());
} else if (!onlyReturnInResponseParams && authorizationRequestCustomAllowedParameters.stream()
.filter(o -> StringUtils.isNotBlank(o.getParamName())
&& o.getParamName().equals(entry.getKey())).findFirst().isPresent()) {
result.put(entry.getKey(), entry.getValue());
}
}
Expand Down Expand Up @@ -213,16 +222,16 @@ public Object getTypedValue(String stringValue, String type) {
* @param customParameters Custom parameters used in the authorization flow.
*/
public void getCustomParameters(JwtAuthorizationRequest jwtRequest, Map<String, String> customParameters) {
Set<String> authorizationRequestCustomAllowedParameters = appConfiguration.getAuthorizationRequestCustomAllowedParameters();
Set<AuthorizationRequestCustomParameter> authorizationRequestCustomAllowedParameters = appConfiguration.getAuthorizationRequestCustomAllowedParameters();

if (authorizationRequestCustomAllowedParameters == null) {
return;
}

JSONObject jsonPayload = jwtRequest.getJsonPayload();
for (String customParam : authorizationRequestCustomAllowedParameters) {
if (jsonPayload.has(customParam)) {
customParameters.put(customParam, jsonPayload.getString(customParam));
for (AuthorizationRequestCustomParameter customParam : authorizationRequestCustomAllowedParameters) {
if (jsonPayload.has(customParam.getParamName())) {
customParameters.put(customParam.getParamName(), jsonPayload.getString(customParam.getParamName()));
}
}
}
Expand Down
Loading