Skip to content

Commit

Permalink
feat(jans-auth-server): added externalUriWhiteList configuration prop…
Browse files Browse the repository at this point in the history
…erty before call external uri from AS #3130 (#3425)
  • Loading branch information
yuriyz authored Dec 27, 2022
1 parent 8385c96 commit 6c7df6f
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 8 deletions.
8 changes: 8 additions & 0 deletions jans-auth-server/agama/engine/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@
</suiteXmlFiles>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>

Expand Down
13 changes: 13 additions & 0 deletions jans-auth-server/agama/model/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,17 @@
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,9 @@ public class AppConfiguration implements Configuration {
@DocProperty(description = "JMS Password")
private String jmsPassword;

@DocProperty(description = "This list specifies which external URIs can be called by AS (if empty any URI can be called)")
private List<String> externalUriWhiteList;

@DocProperty(description = "This list specifies which client redirection URIs are white-listed")
private List<String> clientWhiteList;

Expand Down Expand Up @@ -2473,6 +2476,15 @@ public void setJmsPassword(String jmsPassword) {
this.jmsPassword = jmsPassword;
}

public List<String> getExternalUriWhiteList() {
if (externalUriWhiteList == null) externalUriWhiteList = new ArrayList<>();
return externalUriWhiteList;
}

public void setExternalUriWhiteList(List<String> externalUriWhiteList) {
this.externalUriWhiteList = externalUriWhiteList;
}

public List<String> getClientWhiteList() {
return clientWhiteList;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@
import io.jans.as.model.jwt.Jwt;
import io.jans.as.model.register.RegisterErrorResponseType;
import io.jans.as.model.ssa.SsaValidationType;
import io.jans.as.model.util.JwtUtil;
import io.jans.as.model.util.Pair;
import io.jans.as.server.ciba.CIBARegisterParamsValidatorService;
import io.jans.as.server.model.common.AbstractToken;
import io.jans.as.server.model.common.AuthorizationGrant;
import io.jans.as.server.model.common.AuthorizationGrantList;
import io.jans.as.server.model.registration.RegisterParamsValidator;
import io.jans.as.server.service.external.ExternalDynamicClientRegistrationService;
import io.jans.as.server.service.net.UriService;
import jakarta.ejb.Stateless;
import jakarta.inject.Inject;
import jakarta.inject.Named;
Expand Down Expand Up @@ -78,6 +78,9 @@ public class RegisterValidator {
@Inject
private SsaValidationConfigService ssaValidationConfigService;

@Inject
private UriService uriService;

public void validateNotBlank(String input, String errorReason) {
if (StringUtils.isBlank(input)) {
log.trace("Failed to perform client action, reason: {}", errorReason);
Expand Down Expand Up @@ -191,7 +194,7 @@ private String getJwksString(JSONObject softwareStatement) {
@Nullable
private JSONObject getJwks(HttpServletRequest httpRequest, Jwt jwt, String jwksUri, String jwksStr) {
if (StringUtils.isNotBlank(jwksUri)) {
return JwtUtil.getJSONWebKeys(jwksUri);
return uriService.loadJson(jwksUri);
}

if (StringUtils.isNotBlank(jwksStr)) {
Expand Down Expand Up @@ -259,8 +262,11 @@ public JSONObject validateSoftwareStatement(HttpServletRequest httpServletReques
}

JSONObject jwks = Strings.isNullOrEmpty(jwksUriClaim) ?
new JSONObject(jwksClaim) :
JwtUtil.getJSONWebKeys(jwksUriClaim);
null :
uriService.loadJson(jwksUriClaim);
if (jwks == null && StringUtils.isNotBlank(jwksClaim)) {
jwks = new JSONObject(jwksClaim);
}

boolean validSignature = cryptoProvider.verifySignature(softwareStatement.getSigningInput(),
softwareStatement.getEncodedSignature(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import io.jans.as.model.register.RegisterRequestParam;
import io.jans.as.model.ssa.SsaValidationConfig;
import io.jans.as.model.ssa.SsaValidationType;
import io.jans.as.model.util.JwtUtil;
import io.jans.as.server.service.net.UriService;
import jakarta.ejb.Stateless;
import jakarta.inject.Inject;
import jakarta.inject.Named;
Expand Down Expand Up @@ -42,6 +42,9 @@ public class SsaValidationConfigService {
@Inject
private AbstractCryptoProvider cryptoProvider;

@Inject
private UriService uriService;

public List<SsaValidationConfig> getByIssuer(String issuer, SsaValidationType type) {
if (StringUtils.isBlank(issuer)) {
return new ArrayList<>();
Expand Down Expand Up @@ -130,18 +133,18 @@ private boolean isSignatureValid(Jwt jwt, SsaValidationConfig config) {
private JSONObject loadJwks(SsaValidationConfig config) {
JSONObject jwks = null;
if (StringUtils.isNotBlank(config.getJwksUri())) {
jwks = JwtUtil.getJSONWebKeys(config.getJwksUri());
jwks = uriService.loadJson(config.getJwksUri());
}

if (jwks == null && StringUtils.isNotBlank(config.getJwks())) {
jwks = new JSONObject(config.getJwks());
}

if (jwks == null && StringUtils.isNotBlank(config.getConfigurationEndpoint()) && StringUtils.isNotBlank(config.getConfigurationEndpointClaim())) {
final JSONObject responseJson = JwtUtil.getJSONWebKeys(config.getConfigurationEndpoint());
final JSONObject responseJson = uriService.loadJson(config.getConfigurationEndpoint());
final String jwksEndpoint = responseJson.optString(config.getConfigurationEndpointClaim());
if (StringUtils.isNotBlank(jwksEndpoint)) {
jwks = JwtUtil.getJSONWebKeys(jwksEndpoint);
jwks = uriService.loadJson(jwksEndpoint);
}
}
return jwks;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.jans.as.server.service.net;

import io.jans.as.model.configuration.AppConfiguration;
import io.jans.as.model.util.JwtUtil;
import io.jans.as.model.util.URLPatternList;
import jakarta.ejb.Stateless;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import org.apache.tika.utils.StringUtils;
import org.json.JSONObject;
import org.slf4j.Logger;

import java.util.List;

/**
* @author Yuriy Z
*/
@Stateless
@Named
public class UriService {

@Inject
private Logger log;

@Inject
private AppConfiguration appConfiguration;

public boolean canCall(String uri) {
if (StringUtils.isBlank(uri)) {
return false;
}

final List<String> externalUriWhiteList = appConfiguration.getExternalUriWhiteList();
if (externalUriWhiteList == null || externalUriWhiteList.isEmpty()) {
return true;
}

return new URLPatternList(externalUriWhiteList).isUrlListed(uri);
}

public JSONObject loadJson(String uri) {
if (!canCall(uri)) {
log.debug("Unable to call external uri: {}, externalUriWhiteList: {}", uri, appConfiguration.getExternalUriWhiteList());
return null;
}
return JwtUtil.getJSONWebKeys(uri);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package io.jans.as.server.service.net;

import io.jans.as.model.configuration.AppConfiguration;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;
import org.slf4j.Logger;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

import java.util.ArrayList;
import java.util.Collections;

import static org.mockito.Mockito.when;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.assertFalse;

/**
* @author Yuriy Z
*/
@Listeners(MockitoTestNGListener.class)
public class UriServiceTest {

@InjectMocks
private UriService uriService;

@Mock
private Logger log;

@Mock
private AppConfiguration appConfiguration;

@Test
public void canCall_whenExternalUriWhiteListIsBlank_shouldReturnTrue() {
when(appConfiguration.getExternalUriWhiteList()).thenReturn(new ArrayList<>());

assertTrue(uriService.canCall("http://example.com"));
}

@Test
public void canCall_whenUriAllowedByExternalUriWhiteList_shouldReturnTrue() {
when(appConfiguration.getExternalUriWhiteList()).thenReturn(Collections.singletonList("example.com"));

assertTrue(uriService.canCall("http://example.com"));
}

@Test
public void canCall_whenUriNotAllowedByExternalUriWhiteList_shouldReturnFalse() {
when(appConfiguration.getExternalUriWhiteList()).thenReturn(Collections.singletonList("my.com"));

assertFalse(uriService.canCall("http://example.com"));
}
}
1 change: 1 addition & 0 deletions jans-auth-server/server/src/test/resources/testng.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<class name="io.jans.as.server.service.RedirectionUriServiceTest" />
<class name="io.jans.as.server.service.external.ExternalAuthenticationServiceTest" />
<class name="io.jans.as.server.servlet.OpenIdConfigurationTest" />
<class name="io.jans.as.server.service.net.UriServiceTest" />

<class name="io.jans.as.server.token.ws.rs.TokenExchangeServiceTest" />
<class name="io.jans.as.server.token.ws.rs.TokenRestWebServiceValidatorTest" />
Expand Down

0 comments on commit 6c7df6f

Please sign in to comment.