@Test(timeout = 1000) public void testAlreadyAuthenticatedNotAuthorized(final TestContext testContext) throws Exception { simulatePreviousAuthenticationSuccess(); final AsyncClient<TestCredentials, TestProfile> indirectClient = getMockIndirectClient(NAME); final Clients<AsyncClient<? extends Credentials, ? extends CommonProfile>, AsyncAuthorizationGenerator<CommonProfile>> clients = new Clients<>(CALLBACK_URL, indirectClient); when(config.getClients()).thenReturn(clients); final String authorizers = NAME; addSingleAuthorizerToConfig((context, prof) -> prof.get(0).getId().equals(BAD_USERNAME)); asyncSecurityLogic = new DefaultAsyncSecurityLogic<>(true, false, config, httpActionAdapter); final Async async = testContext.async(); final CompletableFuture<Object> result = simulatePreviousAuthenticationSuccess() .thenCompose(v -> asyncSecurityLogic.perform(webContext, accessGrantedAdapter, null, authorizers, null)); exception.expect(CompletionException.class); exception.expectCause(allOf(IsInstanceOf.instanceOf(HttpAction.class), hasProperty("message", is("forbidden")), hasProperty("code", is(403)))); assertSuccessfulEvaluation(result, ExceptionSoftener.softenConsumer(o -> { assertThat(o, is(nullValue())); assertThat(status.get(), is(403)); verify(accessGrantedAdapter, times(0)).adapt(webContext); }), async); }
@Override public CompletableFuture<R> perform(final C context, final SecurityGrantedAccessAdapter<R, C> securityGrantedAccessAdapter, final String clients, final String authorizers, final String matchers, final Object... parameters) { logger.debug("=== SECURITY ==="); assertNotNull("context", context); HttpAction action; logger.debug("url: {}", context.getFullRequestURL()); logger.debug("matchers: {}", matchers); final CompletableFuture<R> resultFuture = matchingChecker.matches(context, matchers, config.getMatchers()) .thenCompose(b -> { if (b) { logger.debug("clients: {}", clients); final List<AsyncClient<? extends Credentials, U>> currentClients = clientFinder.find(configClients, context, clients); logger.debug("currentClients: {}", currentClients); final boolean loadProfilesFromSession = loadFromSessionDecision.make(context, currentClients); logger.debug("loadProfilesFromSession: {}", loadProfilesFromSession); final AsyncProfileManager<U, C> manager = getProfileManager(context, config); final CompletableFuture<List<U>> profilesFuture = manager.getAll(loadProfilesFromSession); final CompletableFuture<List<U>> profilesAfterDirectAuth = profilesFuture.thenCompose(profiles -> { logger.debug("profiles: {}", profiles); if (isEmpty(profiles) && isNotEmpty(currentClients)) { return directClientAuthenticator.authenticate(currentClients, context, manager); } else { return completedFuture(profiles); } }); return profilesAfterDirectAuth.thenCompose(profiles -> { if (isNotEmpty(profiles)) { logger.debug("authorizers: {}", authorizers); final CompletableFuture<Boolean> authorizedFuture = authorizationChecker.isAuthorized(context, profiles, authorizers, config.getAuthorizers()); return authorizedFuture.thenCompose(authorized -> handleAuthorizationResult(authorized, securityGrantedAccessAdapter, context, parameters)); } else { return directAuthFailedAuthenticator.authenticate(context, currentClients) .handle(ExceptionSoftener.softenBiFunction(AsyncExceptionHandler::extractAsyncHttpAction)) .handle(AsyncExceptionHandler::wrapUnexpectedException) .thenApply(a -> httpActionAdapter.adapt(a.getCode(), context)); } }); } else { return accessApproved(securityGrantedAccessAdapter, context, parameters); } }); return exceptionHandler.applyExceptionHandling(resultFuture, context); }
DefaultAsyncSecurityLogic extends ProfileManagerFactoryAware<C, AsyncProfileManager<U, C>, AsyncConfig<R, U, C>> implements AsyncSecurityLogic<R, C> { @Override public CompletableFuture<R> perform(final C context, final SecurityGrantedAccessAdapter<R, C> securityGrantedAccessAdapter, final String clients, final String authorizers, final String matchers, final Object... parameters) { logger.debug("=== SECURITY ==="); assertNotNull("context", context); HttpAction action; logger.debug("url: {}", context.getFullRequestURL()); logger.debug("matchers: {}", matchers); final CompletableFuture<R> resultFuture = matchingChecker.matches(context, matchers, config.getMatchers()) .thenCompose(b -> { if (b) { logger.debug("clients: {}", clients); final List<AsyncClient<? extends Credentials, U>> currentClients = clientFinder.find(configClients, context, clients); logger.debug("currentClients: {}", currentClients); final boolean loadProfilesFromSession = loadFromSessionDecision.make(context, currentClients); logger.debug("loadProfilesFromSession: {}", loadProfilesFromSession); final AsyncProfileManager<U, C> manager = getProfileManager(context, config); final CompletableFuture<List<U>> profilesFuture = manager.getAll(loadProfilesFromSession); final CompletableFuture<List<U>> profilesAfterDirectAuth = profilesFuture.thenCompose(profiles -> { logger.debug("profiles: {}", profiles); if (isEmpty(profiles) && isNotEmpty(currentClients)) { return directClientAuthenticator.authenticate(currentClients, context, manager); } else { return completedFuture(profiles); } }); return profilesAfterDirectAuth.thenCompose(profiles -> { if (isNotEmpty(profiles)) { logger.debug("authorizers: {}", authorizers); final CompletableFuture<Boolean> authorizedFuture = authorizationChecker.isAuthorized(context, profiles, authorizers, config.getAuthorizers()); return authorizedFuture.thenCompose(authorized -> handleAuthorizationResult(authorized, securityGrantedAccessAdapter, context, parameters)); } else { return directAuthFailedAuthenticator.authenticate(context, currentClients) .handle(ExceptionSoftener.softenBiFunction(AsyncExceptionHandler::extractAsyncHttpAction)) .handle(AsyncExceptionHandler::wrapUnexpectedException) .thenApply(a -> httpActionAdapter.adapt(a.getCode(), context)); } }); } else { return accessApproved(securityGrantedAccessAdapter, context, parameters); } }); return exceptionHandler.applyExceptionHandling(resultFuture, context); } }
DefaultAsyncSecurityLogic extends ProfileManagerFactoryAware<C, AsyncProfileManager<U, C>, AsyncConfig<R, U, C>> implements AsyncSecurityLogic<R, C> { @Override public CompletableFuture<R> perform(final C context, final SecurityGrantedAccessAdapter<R, C> securityGrantedAccessAdapter, final String clients, final String authorizers, final String matchers, final Object... parameters) { logger.debug("=== SECURITY ==="); assertNotNull("context", context); HttpAction action; logger.debug("url: {}", context.getFullRequestURL()); logger.debug("matchers: {}", matchers); final CompletableFuture<R> resultFuture = matchingChecker.matches(context, matchers, config.getMatchers()) .thenCompose(b -> { if (b) { logger.debug("clients: {}", clients); final List<AsyncClient<? extends Credentials, U>> currentClients = clientFinder.find(configClients, context, clients); logger.debug("currentClients: {}", currentClients); final boolean loadProfilesFromSession = loadFromSessionDecision.make(context, currentClients); logger.debug("loadProfilesFromSession: {}", loadProfilesFromSession); final AsyncProfileManager<U, C> manager = getProfileManager(context, config); final CompletableFuture<List<U>> profilesFuture = manager.getAll(loadProfilesFromSession); final CompletableFuture<List<U>> profilesAfterDirectAuth = profilesFuture.thenCompose(profiles -> { logger.debug("profiles: {}", profiles); if (isEmpty(profiles) && isNotEmpty(currentClients)) { return directClientAuthenticator.authenticate(currentClients, context, manager); } else { return completedFuture(profiles); } }); return profilesAfterDirectAuth.thenCompose(profiles -> { if (isNotEmpty(profiles)) { logger.debug("authorizers: {}", authorizers); final CompletableFuture<Boolean> authorizedFuture = authorizationChecker.isAuthorized(context, profiles, authorizers, config.getAuthorizers()); return authorizedFuture.thenCompose(authorized -> handleAuthorizationResult(authorized, securityGrantedAccessAdapter, context, parameters)); } else { return directAuthFailedAuthenticator.authenticate(context, currentClients) .handle(ExceptionSoftener.softenBiFunction(AsyncExceptionHandler::extractAsyncHttpAction)) .handle(AsyncExceptionHandler::wrapUnexpectedException) .thenApply(a -> httpActionAdapter.adapt(a.getCode(), context)); } }); } else { return accessApproved(securityGrantedAccessAdapter, context, parameters); } }); return exceptionHandler.applyExceptionHandling(resultFuture, context); } DefaultAsyncSecurityLogic(final boolean saveProfileInSession,
                                     final boolean multiProfile,
                                     final AsyncConfig<R, U, C> config,
                                     final HttpActionAdapter<R, C> httpActionAdapter);  DefaultAsyncSecurityLogic(final boolean saveProfileInSession,
                                     final boolean multiProfile,
                                     final AsyncConfig<R, U, C> config,
                                     final AsyncExceptionHandler<R> exceptionHandler,
                                     final HttpActionAdapter<R, C> httpActionAdapter); }
DefaultAsyncSecurityLogic extends ProfileManagerFactoryAware<C, AsyncProfileManager<U, C>, AsyncConfig<R, U, C>> implements AsyncSecurityLogic<R, C> { @Override public CompletableFuture<R> perform(final C context, final SecurityGrantedAccessAdapter<R, C> securityGrantedAccessAdapter, final String clients, final String authorizers, final String matchers, final Object... parameters) { logger.debug("=== SECURITY ==="); assertNotNull("context", context); HttpAction action; logger.debug("url: {}", context.getFullRequestURL()); logger.debug("matchers: {}", matchers); final CompletableFuture<R> resultFuture = matchingChecker.matches(context, matchers, config.getMatchers()) .thenCompose(b -> { if (b) { logger.debug("clients: {}", clients); final List<AsyncClient<? extends Credentials, U>> currentClients = clientFinder.find(configClients, context, clients); logger.debug("currentClients: {}", currentClients); final boolean loadProfilesFromSession = loadFromSessionDecision.make(context, currentClients); logger.debug("loadProfilesFromSession: {}", loadProfilesFromSession); final AsyncProfileManager<U, C> manager = getProfileManager(context, config); final CompletableFuture<List<U>> profilesFuture = manager.getAll(loadProfilesFromSession); final CompletableFuture<List<U>> profilesAfterDirectAuth = profilesFuture.thenCompose(profiles -> { logger.debug("profiles: {}", profiles); if (isEmpty(profiles) && isNotEmpty(currentClients)) { return directClientAuthenticator.authenticate(currentClients, context, manager); } else { return completedFuture(profiles); } }); return profilesAfterDirectAuth.thenCompose(profiles -> { if (isNotEmpty(profiles)) { logger.debug("authorizers: {}", authorizers); final CompletableFuture<Boolean> authorizedFuture = authorizationChecker.isAuthorized(context, profiles, authorizers, config.getAuthorizers()); return authorizedFuture.thenCompose(authorized -> handleAuthorizationResult(authorized, securityGrantedAccessAdapter, context, parameters)); } else { return directAuthFailedAuthenticator.authenticate(context, currentClients) .handle(ExceptionSoftener.softenBiFunction(AsyncExceptionHandler::extractAsyncHttpAction)) .handle(AsyncExceptionHandler::wrapUnexpectedException) .thenApply(a -> httpActionAdapter.adapt(a.getCode(), context)); } }); } else { return accessApproved(securityGrantedAccessAdapter, context, parameters); } }); return exceptionHandler.applyExceptionHandling(resultFuture, context); } DefaultAsyncSecurityLogic(final boolean saveProfileInSession,
                                     final boolean multiProfile,
                                     final AsyncConfig<R, U, C> config,
                                     final HttpActionAdapter<R, C> httpActionAdapter);  DefaultAsyncSecurityLogic(final boolean saveProfileInSession,
                                     final boolean multiProfile,
                                     final AsyncConfig<R, U, C> config,
                                     final AsyncExceptionHandler<R> exceptionHandler,
                                     final HttpActionAdapter<R, C> httpActionAdapter); @Override CompletableFuture<R> perform(final C context,
                                        final SecurityGrantedAccessAdapter<R, C> securityGrantedAccessAdapter,
                                        final String clients, final String authorizers, final String matchers,
                                        final Object... parameters); }
DefaultAsyncSecurityLogic extends ProfileManagerFactoryAware<C, AsyncProfileManager<U, C>, AsyncConfig<R, U, C>> implements AsyncSecurityLogic<R, C> { @Override public CompletableFuture<R> perform(final C context, final SecurityGrantedAccessAdapter<R, C> securityGrantedAccessAdapter, final String clients, final String authorizers, final String matchers, final Object... parameters) { logger.debug("=== SECURITY ==="); assertNotNull("context", context); HttpAction action; logger.debug("url: {}", context.getFullRequestURL()); logger.debug("matchers: {}", matchers); final CompletableFuture<R> resultFuture = matchingChecker.matches(context, matchers, config.getMatchers()) .thenCompose(b -> { if (b) { logger.debug("clients: {}", clients); final List<AsyncClient<? extends Credentials, U>> currentClients = clientFinder.find(configClients, context, clients); logger.debug("currentClients: {}", currentClients); final boolean loadProfilesFromSession = loadFromSessionDecision.make(context, currentClients); logger.debug("loadProfilesFromSession: {}", loadProfilesFromSession); final AsyncProfileManager<U, C> manager = getProfileManager(context, config); final CompletableFuture<List<U>> profilesFuture = manager.getAll(loadProfilesFromSession); final CompletableFuture<List<U>> profilesAfterDirectAuth = profilesFuture.thenCompose(profiles -> { logger.debug("profiles: {}", profiles); if (isEmpty(profiles) && isNotEmpty(currentClients)) { return directClientAuthenticator.authenticate(currentClients, context, manager); } else { return completedFuture(profiles); } }); return profilesAfterDirectAuth.thenCompose(profiles -> { if (isNotEmpty(profiles)) { logger.debug("authorizers: {}", authorizers); final CompletableFuture<Boolean> authorizedFuture = authorizationChecker.isAuthorized(context, profiles, authorizers, config.getAuthorizers()); return authorizedFuture.thenCompose(authorized -> handleAuthorizationResult(authorized, securityGrantedAccessAdapter, context, parameters)); } else { return directAuthFailedAuthenticator.authenticate(context, currentClients) .handle(ExceptionSoftener.softenBiFunction(AsyncExceptionHandler::extractAsyncHttpAction)) .handle(AsyncExceptionHandler::wrapUnexpectedException) .thenApply(a -> httpActionAdapter.adapt(a.getCode(), context)); } }); } else { return accessApproved(securityGrantedAccessAdapter, context, parameters); } }); return exceptionHandler.applyExceptionHandling(resultFuture, context); } DefaultAsyncSecurityLogic(final boolean saveProfileInSession,
                                     final boolean multiProfile,
                                     final AsyncConfig<R, U, C> config,
                                     final HttpActionAdapter<R, C> httpActionAdapter);  DefaultAsyncSecurityLogic(final boolean saveProfileInSession,
                                     final boolean multiProfile,
                                     final AsyncConfig<R, U, C> config,
                                     final AsyncExceptionHandler<R> exceptionHandler,
                                     final HttpActionAdapter<R, C> httpActionAdapter); @Override CompletableFuture<R> perform(final C context,
                                        final SecurityGrantedAccessAdapter<R, C> securityGrantedAccessAdapter,
                                        final String clients, final String authorizers, final String matchers,
                                        final Object... parameters);  }