/** * Calls each {@code AsyncServerAuthContext} in parallel to clean the client subject and only * return a successful promise if all complete successfully otherwise returns the first exception * in a failed promise. * * @param context {@inheritDoc} * @param clientSubject {@inheritDoc} * @return {@inheritDoc} */ @Override public Promise<Void, AuthenticationException> cleanSubject( MessageContext context, Subject clientSubject) { List<Promise<Void, AuthenticationException>> promises = new ArrayList<>(); for (AsyncServerAuthModule serverAuthModule : authModules) { promises.add(serverAuthModule.cleanSubject(context, clientSubject)); } return Promises.when(promises).thenAsync(ON_SUCCESS_RETURN_VOID); }
@Test public void adaptedAsyncServerAuthModuleShouldAdaptGetModuleIdCall() { // Given ServerAuthModule authModule = mock(ServerAuthModule.class); // When AsyncServerAuthModule asyncAuthModule = JaspiAdapters.adapt(authModule); String moduleId = asyncAuthModule.getModuleId(); // Then Assertions.assertThat(moduleId).isEqualTo(authModule.getClass().getCanonicalName()); }
@Test public void adaptedAsyncServerAuthModuleShouldAdaptGetSupportedMessageTypesCall() { // Given ServerAuthModule authModule = mock(ServerAuthModule.class); given(authModule.getSupportedMessageTypes()) .willReturn(new Class<?>[] {Request.class, Response.class}); // When AsyncServerAuthModule asyncAuthModule = JaspiAdapters.adapt(authModule); asyncAuthModule.getSupportedMessageTypes(); // Then verify(authModule).getSupportedMessageTypes(); }
@Test public void adaptedAsyncServerAuthModuleShouldAdaptSuccessfulCleanSubjectCall() throws AuthException { // Given ServerAuthModule authModule = mock(ServerAuthModule.class); MessageInfoContext messageInfo = mock(MessageInfoContext.class); Subject clientSubject = new Subject(); // When AsyncServerAuthModule asyncAuthModule = JaspiAdapters.adapt(authModule); Promise<Void, AuthenticationException> promise = asyncAuthModule.cleanSubject(messageInfo, clientSubject); // Then assertThat(promise).succeeded().withObject().isNull(); verify(authModule).cleanSubject(any(MessageInfo.class), eq(clientSubject)); }
/** * Secures the response message using the same {@code AsyncServerAuthModule} that authenticated * the incoming request message. * * <p>If no {@code AsyncServerAuthModule} authenticated the incoming request message, then this * method should not have been called and a failed promise will be return with an {@code * AuthenticationException}. * * @param context {@inheritDoc} * @param serviceSubject {@inheritDoc} * @return {@inheritDoc} */ @Override public Promise<AuthStatus, AuthenticationException> secureResponse( MessageContext context, Subject serviceSubject) { FallbackAuthContextState state = context.getState(this); if (state.getAuthenticatedAuthModuleIndex() < 0) { return Promises.newExceptionPromise( new AuthenticationException( "No auth module authenticated the incoming request message. " + "Cannot secure response message.")); } AsyncServerAuthModule authModule = authModules.get(state.getAuthenticatedAuthModuleIndex()); logger.debug( "Using authenticating auth module from private context map, {}, to secure the response", authModule.getModuleId()); return authModule.secureResponse(context, serviceSubject); }
@Test public void adaptedAsyncServerAuthModuleShouldAdaptFailedCleanSubjectCall() throws AuthException { // Given ServerAuthModule authModule = mock(ServerAuthModule.class); MessageInfoContext messageInfo = mock(MessageInfoContext.class); Subject clientSubject = new Subject(); doThrow(AuthException.class) .when(authModule) .cleanSubject(any(MessageInfo.class), eq(clientSubject)); // When AsyncServerAuthModule asyncAuthModule = JaspiAdapters.adapt(authModule); Promise<Void, AuthenticationException> promise = asyncAuthModule.cleanSubject(messageInfo, clientSubject); // Then assertThat(promise).failedWithException().isInstanceOf(AuthenticationException.class); }
@Test public void adaptedAsyncServerAuthModuleShouldAdaptSuccessfulSecureResponseCall() throws AuthException { // Given ServerAuthModule authModule = mock(ServerAuthModule.class); MessageInfoContext messageInfo = mock(MessageInfoContext.class); Subject serviceSubject = new Subject(); given(authModule.secureResponse(any(MessageInfo.class), eq(serviceSubject))) .willReturn(AuthStatus.SEND_SUCCESS); // When AsyncServerAuthModule asyncAuthModule = JaspiAdapters.adapt(authModule); Promise<AuthStatus, AuthenticationException> promise = asyncAuthModule.secureResponse(messageInfo, serviceSubject); // Then assertThat(promise).succeeded().withObject().isEqualTo(AuthStatus.SEND_SUCCESS); }
@Test public void adaptedAsyncServerAuthModuleShouldAdaptSuccessfulGetInitializeCall() throws AuthException { // Given ServerAuthModule authModule = mock(ServerAuthModule.class); MessagePolicy requestPolicy = mock(MessagePolicy.class); MessagePolicy responsePolicy = mock(MessagePolicy.class); CallbackHandler handler = mock(CallbackHandler.class); Map<String, Object> options = Collections.emptyMap(); // When AsyncServerAuthModule asyncAuthModule = JaspiAdapters.adapt(authModule); Promise<Void, AuthenticationException> promise = asyncAuthModule.initialize(requestPolicy, responsePolicy, handler, options); // Then assertThat(promise).succeeded().withObject().isNull(); verify(authModule).initialize(requestPolicy, responsePolicy, handler, options); }
@Test public void adaptedAsyncServerAuthModuleShouldAdaptFailedSecureResponseCall() throws AuthException { // Given ServerAuthModule authModule = mock(ServerAuthModule.class); MessageInfoContext messageInfo = mock(MessageInfoContext.class); Subject serviceSubject = new Subject(); doThrow(AuthException.class) .when(authModule) .secureResponse(any(MessageInfo.class), eq(serviceSubject)); // When AsyncServerAuthModule asyncAuthModule = JaspiAdapters.adapt(authModule); Promise<AuthStatus, AuthenticationException> promise = asyncAuthModule.secureResponse(messageInfo, serviceSubject); // Then assertThat(promise).failedWithException().isInstanceOf(AuthenticationException.class); }
private Promise<AuthStatus, AuthenticationException> validateRequest( final MessageInfoContext messageInfo, final Subject clientSubject, final Subject serviceSubject) { if (position < authModules.size()) { final AsyncServerAuthModule authModule = authModules.get(position); return authModule .validateRequest(messageInfo, clientSubject, serviceSubject) .thenOnResult( new ResultHandler<AuthStatus>() { @Override public void handleResult(AuthStatus authStatus) { if (isSuccess(authStatus)) { /* * Save the index of the authenticating module so that it can * be retrieved when securing the response */ logger.trace( "Adding authenticating auth module to private context map, {}", authModule.getClass().getSimpleName()); state.setAuthenticatedAuthModuleIndex(position); } } }) .thenAsync( new AsyncFunction<AuthStatus, AuthStatus, AuthenticationException>() { @Override public Promise<AuthStatus, AuthenticationException> apply(AuthStatus authStatus) { if (isSendFailure(authStatus)) { return next().validateRequest(messageInfo, clientSubject, serviceSubject); } else { return Promises.newResultPromise(authStatus); } } }); } else { return Promises.newResultPromise(AuthStatus.SEND_FAILURE); } }
@Test public void adaptedAsyncServerAuthModuleShouldAdaptFailedGetInitializeCall() throws AuthException { // Given ServerAuthModule authModule = mock(ServerAuthModule.class); MessagePolicy requestPolicy = mock(MessagePolicy.class); MessagePolicy responsePolicy = mock(MessagePolicy.class); CallbackHandler handler = mock(CallbackHandler.class); Map<String, Object> options = Collections.emptyMap(); doThrow(AuthException.class) .when(authModule) .initialize(requestPolicy, responsePolicy, handler, options); // When AsyncServerAuthModule asyncAuthModule = JaspiAdapters.adapt(authModule); Promise<Void, AuthenticationException> promise = asyncAuthModule.initialize(requestPolicy, responsePolicy, handler, options); // Then assertThat(promise).failedWithException().isInstanceOf(AuthenticationException.class); }