Skip to content

Commit

Permalink
feat(jans-auth-server): block authentication flow originating from a …
Browse files Browse the repository at this point in the history
…webview (#3204)
  • Loading branch information
Milton-Ch authored Dec 5, 2022
1 parent db5a44f commit e48380e
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,9 @@ public class AppConfiguration implements Configuration {
@DocProperty(description = "SSA Configuration")
private SsaConfiguration ssaConfiguration;

@DocProperty(description = "Enable/Disable block authorizations that originate from Webview (Mobile apps).", defaultValue = "false")
private Boolean blockWebviewAuthorizationEnabled = false;

public List<SsaValidationConfig> getDcrSsaValidationConfigs() {
if (dcrSsaValidationConfigs == null) dcrSsaValidationConfigs = new ArrayList<>();
return dcrSsaValidationConfigs;
Expand Down Expand Up @@ -3085,4 +3088,12 @@ public SsaConfiguration getSsaConfiguration() {
public void setSsaConfiguration(SsaConfiguration ssaConfiguration) {
this.ssaConfiguration = ssaConfiguration;
}

public Boolean getBlockWebviewAuthorizationEnabled() {
return blockWebviewAuthorizationEnabled;
}

public void setBlockWebviewAuthorizationEnabled(Boolean blockWebviewAuthorizationEnabled) {
this.blockWebviewAuthorizationEnabled = blockWebviewAuthorizationEnabled;
}
}
3 changes: 2 additions & 1 deletion jans-auth-server/server/conf/jans-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -449,5 +449,6 @@
"defaultResponseHeaders": {
"Cache-Control": "max-age=0, no-store"
}
}
},
"blockWebviewAuthorizationEnabled": false
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ public Response requestAuthorizationGet(
String codeChallenge, String codeChallengeMethod, String customResponseHeaders, String claims, String authReqId,
HttpServletRequest httpRequest, HttpServletResponse httpResponse, SecurityContext securityContext) {

authorizeRestWebServiceValidator.validateNotWebView(httpRequest);

AuthzRequest authzRequest = new AuthzRequest();
authzRequest.setHttpMethod(HttpMethod.GET);
authzRequest.setScope(scope);
Expand Down Expand Up @@ -210,6 +212,8 @@ public Response requestAuthorizationPost(
String codeChallenge, String codeChallengeMethod, String customResponseHeaders, String claims, String authReqId,
HttpServletRequest httpRequest, HttpServletResponse httpResponse, SecurityContext securityContext) {

authorizeRestWebServiceValidator.validateNotWebView(httpRequest);

AuthzRequest authzRequest = new AuthzRequest();
authzRequest.setHttpMethod(HttpMethod.POST);
authzRequest.setScope(scope);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -458,4 +458,14 @@ public void checkSignedRequestRequired(AuthzRequest authzRequest) {
throw createInvalidJwtRequestException(authzRequest.getRedirectUriResponse(), "A signed request object is required");
}
}

public void validateNotWebView(HttpServletRequest httpRequest) {
if (appConfiguration.getBlockWebviewAuthorizationEnabled()) {
String headerRequestedWith = httpRequest.getHeader("X-Requested-With");
if (headerRequestedWith != null) {
log.error("Unauthorized, request contains X-Requested-With: {}", headerRequestedWith);
throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED).build());
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@
import io.jans.as.server.service.DeviceAuthorizationService;
import io.jans.as.server.service.RedirectionUriService;
import io.jans.as.server.service.SessionIdService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.ws.rs.WebApplicationException;
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 static org.mockito.Mockito.when;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import static org.mockito.Mockito.*;
import static org.testng.Assert.*;

/**
* @author Yuriy Z
Expand Down Expand Up @@ -74,4 +75,33 @@ public void isAuthnMaxAgeValid_whenMaxAgeIsZeroAndDisableAuthnForMaxAgeZeroIsTru
public void isAuthnMaxAgeValid_whenMaxAgeIsNull_shouldReturnTrue() {
assertTrue(authorizeRestWebServiceValidator.isAuthnMaxAgeValid(0, new SessionId(), new Client()));
}

@Test
public void validateNotWebView_blockWebviewDisabled_valid() {
HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
when(appConfiguration.getBlockWebviewAuthorizationEnabled()).thenReturn(false);

authorizeRestWebServiceValidator.validateNotWebView(httpServletRequest);
verifyNoInteractions(log, httpServletRequest);
}

@Test
public void validateNotWebView_blockWebviewEnabled_valid() {
HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
when(appConfiguration.getBlockWebviewAuthorizationEnabled()).thenReturn(true);

authorizeRestWebServiceValidator.validateNotWebView(httpServletRequest);
verifyNoInteractions(log);
}

@Test
public void validateNotWebView_withRequestedWithHeader_throwUnauthorized() {
HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
when(appConfiguration.getBlockWebviewAuthorizationEnabled()).thenReturn(true);
String testPackage = "test.app.package";
when(httpServletRequest.getHeader(any())).thenReturn(testPackage);

assertThrows(WebApplicationException.class, () -> authorizeRestWebServiceValidator.validateNotWebView(httpServletRequest));
verify(log).error(anyString(), eq(testPackage));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -394,5 +394,6 @@
"staticKid": "%(static_kid)s",
"forceOfflineAccessScopeToEnableRefreshToken" : false,
"redirectUrisRegexEnabled": false,
"useHighestLevelScriptIfAcrScriptNotFound": true
"useHighestLevelScriptIfAcrScriptNotFound": true,
"blockWebviewAuthorizationEnabled": false
}
Original file line number Diff line number Diff line change
Expand Up @@ -497,5 +497,6 @@
"defaultResponseHeaders": {
"Cache-Control": "max-age=0, no-store"
}
}
},
"blockWebviewAuthorizationEnabled": false
}

0 comments on commit e48380e

Please sign in to comment.