Skip to content

Commit

Permalink
feat(jans-auth-server): reject par without pkce for fapi
Browse files Browse the repository at this point in the history
  • Loading branch information
yuriyz committed Feb 28, 2022
1 parent 363cf0e commit 332df41
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ public Response requestPushedAuthorizationRequest(
+ "customRespHeaders = {}, claims = {}, tokenBindingHeader = {}",
acrValuesStr, amrValuesStr, originHeaders, codeChallenge, codeChallengeMethod, customResponseHeaders, claims, tokenBindingHeader);

parValidator.validatePkce(codeChallenge, state);

List<ResponseType> responseTypes = ResponseType.fromString(responseType, " ");
ResponseMode responseModeObj = ResponseMode.getByValue(responseMode);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import java.util.Date;
import java.util.Set;

Expand Down Expand Up @@ -167,4 +168,16 @@ private void setStateIntoPar(@NotNull RedirectUriResponse redirectUriResponse, @
redirectUriResponse.setState("");
}
}

public void validatePkce(String codeChallenge, String state) {
if (!appConfiguration.isFapi()) {
return;
}
if (StringUtils.isBlank(codeChallenge)) {
throw new WebApplicationException(Response
.status(Response.Status.BAD_REQUEST)
.entity(errorResponseFactory.getErrorAsJson(AuthorizeErrorResponseType.INVALID_REQUEST, state, ""))
.build());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package io.jans.as.server.par.ws.rs;

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

import javax.ws.rs.WebApplicationException;

import static org.mockito.Mockito.when;

/**
* @author Yuriy Zabrovarnyy
*/
@Listeners(MockitoTestNGListener.class)
public class ParValidatorTest {

@InjectMocks
private ParValidator parValidator;

@Mock
private AppConfiguration appConfiguration;

@Mock
private ErrorResponseFactory errorResponseFactory; // mock is required

@SuppressWarnings("java:S5976") // we do want separate methods with clear names. Clarity of use case.
@Test
public void validatePkce_whenFapiIsFalse_shouldNotThrowError() {
when(appConfiguration.isFapi()).thenReturn(false);

parValidator.validatePkce(null, null);
}

@Test(expectedExceptions = WebApplicationException.class)
public void validatePkce_whenFapiIsTrueAndNoCodeChallenage_shouldThrowError() {
when(appConfiguration.isFapi()).thenReturn(true);

parValidator.validatePkce(null, null);
}

@Test
public void validatePkce_whenFapiIsTrueAndCodeChallenageIsSet_shouldNotThrowError() {
when(appConfiguration.isFapi()).thenReturn(true);

parValidator.validatePkce("codechallangehere", null);
}

}

0 comments on commit 332df41

Please sign in to comment.