Search in sources :

Example 1 with AuthenticationFailedException

use of io.quarkus.security.AuthenticationFailedException in project quarkus-resteasy-problem by TietoEVRY.

the class AuthenticationFailedExceptionMapperTest method shouldProduceHttp401.

@Test
void shouldProduceHttp401() {
    AuthenticationFailedException exception = new AuthenticationFailedException();
    Response response = mapper.toResponse(exception);
    assertThat(response.getStatus()).isEqualTo(401);
}
Also used : Response(javax.ws.rs.core.Response) AuthenticationFailedException(io.quarkus.security.AuthenticationFailedException) Test(org.junit.jupiter.api.Test)

Example 2 with AuthenticationFailedException

use of io.quarkus.security.AuthenticationFailedException in project quarkus by quarkusio.

the class QuarkusIdentityProviderManagerImpl method handleProvider.

private <T extends AuthenticationRequest> Uni<SecurityIdentity> handleProvider(int pos, List<IdentityProvider<T>> providers, T request, AuthenticationRequestContext context) {
    if (pos == providers.size()) {
        // we failed to authentication
        log.debug("Authentication failed as providers would authenticate the request");
        return Uni.createFrom().failure(new AuthenticationFailedException());
    }
    IdentityProvider<T> current = providers.get(pos);
    Uni<SecurityIdentity> cs = current.authenticate(request, context).onItem().transformToUni(new Function<SecurityIdentity, Uni<? extends SecurityIdentity>>() {

        @Override
        public Uni<SecurityIdentity> apply(SecurityIdentity securityIdentity) {
            if (securityIdentity != null) {
                return Uni.createFrom().item(securityIdentity);
            }
            return handleProvider(pos + 1, providers, request, context);
        }
    });
    return cs.onItem().transformToUni(new Function<SecurityIdentity, Uni<? extends SecurityIdentity>>() {

        @Override
        public Uni<? extends SecurityIdentity> apply(SecurityIdentity securityIdentity) {
            return handleIdentityFromProvider(0, securityIdentity, context);
        }
    });
}
Also used : SecurityIdentity(io.quarkus.security.identity.SecurityIdentity) Uni(io.smallrye.mutiny.Uni) AuthenticationFailedException(io.quarkus.security.AuthenticationFailedException)

Example 3 with AuthenticationFailedException

use of io.quarkus.security.AuthenticationFailedException in project quarkus by quarkusio.

the class UndertowDeploymentRecorder method bootServletContainer.

public DeploymentManager bootServletContainer(RuntimeValue<DeploymentInfo> info, BeanContainer beanContainer, LaunchMode launchMode, ShutdownContext shutdownContext) {
    if (info.getValue().getExceptionHandler() == null) {
        // if a 500 error page has not been mapped we change the default to our more modern one, with a UID in the
        // log. If this is not production we also include the stack trace
        boolean alreadyMapped = false;
        for (ErrorPage i : info.getValue().getErrorPages()) {
            if (i.getErrorCode() != null && i.getErrorCode() == StatusCodes.INTERNAL_SERVER_ERROR) {
                alreadyMapped = true;
                break;
            }
        }
        if (!alreadyMapped || launchMode.isDevOrTest()) {
            info.getValue().setExceptionHandler(new QuarkusExceptionHandler());
            info.getValue().addErrorPage(new ErrorPage("/@QuarkusError", StatusCodes.INTERNAL_SERVER_ERROR));
            info.getValue().addServlet(new ServletInfo("@QuarkusError", QuarkusErrorServlet.class).addMapping("/@QuarkusError").setAsyncSupported(true).addInitParam(QuarkusErrorServlet.SHOW_STACK, Boolean.toString(launchMode.isDevOrTest())));
        }
    }
    setupRequestScope(info.getValue(), beanContainer);
    try {
        ClassIntrospecter defaultVal = info.getValue().getClassIntrospecter();
        info.getValue().setClassIntrospecter(new ClassIntrospecter() {

            @Override
            public <T> InstanceFactory<T> createInstanceFactory(Class<T> clazz) throws NoSuchMethodException {
                BeanContainer.Factory<T> res = beanContainer.instanceFactory(clazz);
                if (res == null) {
                    return defaultVal.createInstanceFactory(clazz);
                }
                return new InstanceFactory<T>() {

                    @Override
                    public InstanceHandle<T> createInstance() throws InstantiationException {
                        BeanContainer.Instance<T> ih = res.create();
                        return new InstanceHandle<T>() {

                            @Override
                            public T getInstance() {
                                return ih.get();
                            }

                            @Override
                            public void release() {
                                ih.close();
                            }
                        };
                    }
                };
            }
        });
        ExceptionHandler existing = info.getValue().getExceptionHandler();
        info.getValue().setExceptionHandler(new ExceptionHandler() {

            @Override
            public boolean handleThrowable(HttpServerExchange exchange, ServletRequest request, ServletResponse response, Throwable throwable) {
                if (throwable instanceof AuthenticationFailedException || throwable instanceof UnauthorizedException) {
                    String location = servletContext.getDeployment().getErrorPages().getErrorLocation(throwable);
                    // if these have been mapped we use the mapping
                    if (location == null || location.equals("/@QuarkusError")) {
                        if (throwable instanceof AuthenticationFailedException || exchange.getSecurityContext().getAuthenticatedAccount() == null) {
                            if (!exchange.isResponseStarted()) {
                                exchange.getSecurityContext().setAuthenticationRequired();
                                if (exchange.getSecurityContext().authenticate()) {
                                    // if we can authenticate then the request is just forbidden
                                    // this can happen with lazy auth
                                    exchange.setStatusCode(StatusCodes.FORBIDDEN);
                                }
                            }
                        } else {
                            exchange.setStatusCode(StatusCodes.FORBIDDEN);
                        }
                        return true;
                    }
                } else if (throwable instanceof ForbiddenException) {
                    String location = servletContext.getDeployment().getErrorPages().getErrorLocation(throwable);
                    // if these have been mapped we use the mapping
                    if (location == null || location.equals("/@QuarkusError")) {
                        exchange.setStatusCode(StatusCodes.FORBIDDEN);
                        return true;
                    }
                }
                return existing.handleThrowable(exchange, request, response, throwable);
            }
        });
        ServletContainer servletContainer = Servlets.defaultContainer();
        DeploymentManager manager = servletContainer.addDeployment(info.getValue());
        manager.deploy();
        manager.start();
        servletContext = manager.getDeployment().getServletContext();
        shutdownContext.addShutdownTask(new Runnable() {

            @Override
            public void run() {
                servletContext = null;
            }
        });
        return manager;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
Also used : ServletRequest(javax.servlet.ServletRequest) ErrorPage(io.undertow.servlet.api.ErrorPage) Instance(javax.enterprise.inject.Instance) AuthenticationFailedException(io.quarkus.security.AuthenticationFailedException) DeploymentManager(io.undertow.servlet.api.DeploymentManager) ImmediateAuthenticationMechanismFactory(io.undertow.util.ImmediateAuthenticationMechanismFactory) InstanceFactory(io.undertow.servlet.api.InstanceFactory) ServletInfo(io.undertow.servlet.api.ServletInfo) ExceptionHandler(io.undertow.servlet.api.ExceptionHandler) HttpServerExchange(io.undertow.server.HttpServerExchange) UnauthorizedException(io.quarkus.security.UnauthorizedException) ServletResponse(javax.servlet.ServletResponse) ForbiddenException(io.quarkus.security.ForbiddenException) ClassIntrospecter(io.undertow.servlet.api.ClassIntrospecter) AuthenticationFailedException(io.quarkus.security.AuthenticationFailedException) IOException(java.io.IOException) ServletException(javax.servlet.ServletException) ForbiddenException(io.quarkus.security.ForbiddenException) UnauthorizedException(io.quarkus.security.UnauthorizedException) InstanceFactory(io.undertow.servlet.api.InstanceFactory) ServletContainer(io.undertow.servlet.api.ServletContainer) InstanceHandle(io.undertow.servlet.api.InstanceHandle)

Example 4 with AuthenticationFailedException

use of io.quarkus.security.AuthenticationFailedException in project quarkus by quarkusio.

the class QuarkusErrorHandler method handle.

@Override
public void handle(RoutingContext event) {
    try {
        if (event.failure() == null) {
            event.response().setStatusCode(event.statusCode());
            event.response().end();
            return;
        }
        // this can happen if there is no auth mechanisms
        if (event.failure() instanceof UnauthorizedException) {
            HttpAuthenticator authenticator = event.get(HttpAuthenticator.class.getName());
            if (authenticator != null) {
                authenticator.sendChallenge(event).subscribe().with(new Consumer<Boolean>() {

                    @Override
                    public void accept(Boolean aBoolean) {
                        event.response().end();
                    }
                }, new Consumer<Throwable>() {

                    @Override
                    public void accept(Throwable throwable) {
                        event.fail(throwable);
                    }
                });
            } else {
                event.response().setStatusCode(HttpResponseStatus.UNAUTHORIZED.code()).end();
            }
            return;
        }
        if (event.failure() instanceof ForbiddenException) {
            event.response().setStatusCode(HttpResponseStatus.FORBIDDEN.code()).end();
            return;
        }
        if (event.failure() instanceof AuthenticationFailedException) {
            // generally this should be handled elsewhere
            // but if we get to this point bad things have happened
            // so it is better to send a response than to hang
            event.response().setStatusCode(HttpResponseStatus.UNAUTHORIZED.code()).end();
            return;
        }
    } catch (IllegalStateException e) {
        // ignore this if the response is already started
        if (!event.response().ended()) {
            // could be that just the head is committed
            event.response().end();
        }
        return;
    }
    if (!event.response().headWritten()) {
        event.response().setStatusCode(event.statusCode() > 0 ? event.statusCode() : 500);
    }
    String uuid = BASE_ID + ERROR_COUNT.incrementAndGet();
    String details;
    String stack = "";
    Throwable exception = event.failure();
    String responseContentType = null;
    try {
        responseContentType = ContentTypes.pickFirstSupportedAndAcceptedContentType(event);
    } catch (RuntimeException e) {
        // Let's shield ourselves from bugs in this parsing code:
        // we're already handling an exception,
        // so the priority is to return *something* to the user.
        // If we can't pick the appropriate content-type, well, so be it.
        exception.addSuppressed(e);
    }
    if (showStack && exception != null) {
        details = generateHeaderMessage(exception, uuid);
        stack = generateStackTrace(exception);
    } else {
        details = generateHeaderMessage(uuid);
    }
    if (event.failure() instanceof IOException) {
        log.debugf(exception, "IOError processing HTTP request to %s failed, the client likely terminated the connection. Error id: %s", event.request().uri(), uuid);
    } else {
        log.errorf(exception, "HTTP Request to %s failed, error id: %s", event.request().uri(), uuid);
    }
    // if not we just return
    if (event.response().ended()) {
        return;
    } else if (event.response().headWritten()) {
        event.response().end();
        return;
    }
    if (responseContentType == null) {
        responseContentType = "";
    }
    switch(responseContentType) {
        case ContentTypes.TEXT_HTML:
        case ContentTypes.APPLICATION_XHTML:
        case ContentTypes.APPLICATION_XML:
        case ContentTypes.TEXT_XML:
            htmlResponse(event, details, exception);
            break;
        case ContentTypes.APPLICATION_JSON:
        case ContentTypes.TEXT_JSON:
            jsonResponse(event, responseContentType, details, stack);
            break;
        default:
            // We default to JSON representation
            switch(contentTypeDefault.orElse(HttpConfiguration.PayloadHint.JSON)) {
                case HTML:
                    htmlResponse(event, details, exception);
                    break;
                case JSON:
                default:
                    jsonResponse(event, ContentTypes.APPLICATION_JSON, details, stack);
                    break;
            }
            break;
    }
}
Also used : ForbiddenException(io.quarkus.security.ForbiddenException) AuthenticationFailedException(io.quarkus.security.AuthenticationFailedException) HttpAuthenticator(io.quarkus.vertx.http.runtime.security.HttpAuthenticator) IOException(java.io.IOException) UnauthorizedException(io.quarkus.security.UnauthorizedException)

Example 5 with AuthenticationFailedException

use of io.quarkus.security.AuthenticationFailedException in project quarkus by quarkusio.

the class BasicAuthenticationMechanism method authenticate.

@Override
public Uni<SecurityIdentity> authenticate(RoutingContext context, IdentityProviderManager identityProviderManager) {
    List<String> authHeaders = context.request().headers().getAll(HttpHeaderNames.AUTHORIZATION);
    if (authHeaders != null) {
        for (String current : authHeaders) {
            if (current.toLowerCase(Locale.ENGLISH).startsWith(LOWERCASE_BASIC_PREFIX)) {
                String base64Challenge = current.substring(PREFIX_LENGTH);
                String plainChallenge = null;
                byte[] decode = Base64.getDecoder().decode(base64Challenge);
                Charset charset = this.charset;
                if (!userAgentCharsets.isEmpty()) {
                    String ua = context.request().headers().get(HttpHeaderNames.USER_AGENT);
                    if (ua != null) {
                        for (Map.Entry<Pattern, Charset> entry : userAgentCharsets.entrySet()) {
                            if (entry.getKey().matcher(ua).find()) {
                                charset = entry.getValue();
                                break;
                            }
                        }
                    }
                }
                plainChallenge = new String(decode, charset);
                int colonPos;
                if ((colonPos = plainChallenge.indexOf(COLON)) > -1) {
                    String userName = plainChallenge.substring(0, colonPos);
                    char[] password = plainChallenge.substring(colonPos + 1).toCharArray();
                    log.debugf("Found basic auth header %s:***** (decoded using charset %s)", userName, charset);
                    UsernamePasswordAuthenticationRequest credential = new UsernamePasswordAuthenticationRequest(userName, new PasswordCredential(password));
                    HttpSecurityUtils.setRoutingContextAttribute(credential, context);
                    context.put(HttpAuthenticationMechanism.class.getName(), this);
                    return identityProviderManager.authenticate(credential);
                }
                // it was not correctly structured.
                return Uni.createFrom().failure(new AuthenticationFailedException());
            }
        }
    }
    // No suitable header has been found in this request,
    return Uni.createFrom().optional(Optional.empty());
}
Also used : Pattern(java.util.regex.Pattern) AuthenticationFailedException(io.quarkus.security.AuthenticationFailedException) PasswordCredential(io.quarkus.security.credential.PasswordCredential) Charset(java.nio.charset.Charset) UsernamePasswordAuthenticationRequest(io.quarkus.security.identity.request.UsernamePasswordAuthenticationRequest) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Aggregations

AuthenticationFailedException (io.quarkus.security.AuthenticationFailedException)22 SecurityIdentity (io.quarkus.security.identity.SecurityIdentity)7 QuarkusSecurityIdentity (io.quarkus.security.runtime.QuarkusSecurityIdentity)7 Uni (io.smallrye.mutiny.Uni)4 InvalidJwtException (org.jose4j.jwt.consumer.InvalidJwtException)4 AuthenticationCompletionException (io.quarkus.security.AuthenticationCompletionException)3 AuthenticationRedirectException (io.quarkus.security.AuthenticationRedirectException)3 UsernamePasswordAuthenticationRequest (io.quarkus.security.identity.request.UsernamePasswordAuthenticationRequest)3 AccessTokenCredential (io.quarkus.oidc.AccessTokenCredential)2 IdTokenCredential (io.quarkus.oidc.IdTokenCredential)2 ForbiddenException (io.quarkus.security.ForbiddenException)2 UnauthorizedException (io.quarkus.security.UnauthorizedException)2 PasswordCredential (io.quarkus.security.credential.PasswordCredential)2 QuarkusPrincipal (io.quarkus.security.runtime.QuarkusPrincipal)2 JsonObject (io.vertx.core.json.JsonObject)2 RoutingContext (io.vertx.ext.web.RoutingContext)2 IOException (java.io.IOException)2 Principal (java.security.Principal)2 Base64Utils (com.redhat.cloud.notifications.Base64Utils)1 X_RH_IDENTITY_HEADER (com.redhat.cloud.notifications.Constants.X_RH_IDENTITY_HEADER)1