@Override
    public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) throws Exception {
        return HttpResponse.of(authorizer.authorize(ctx, req).handle((result, cause) -> {
            if (cause == null && result) {
                // Already authenticated.
                try {
                    return unwrap().serve(ctx, req);
                } catch (Exception e) {
                    return Exceptions.throwUnsafely(e);
                }
            }

            final CompletionStage<SamlIdentityProviderConfig> f;
            if (portConfigHolder.isDone()) {
                f = sp.idpConfigSelector().select(sp, ctx, req);
            } else {
                f = portConfigHolder.future().thenCompose(
                        unused -> sp.idpConfigSelector().select(sp, ctx, req));
            }
            // Find an identity provider first where the request is to be sent to.
            return HttpResponse.of(f.thenApply(idp -> {
                if (idp == null) {
                    throw new RuntimeException("cannot find a suitable identity provider from configurations");
                }
                final String defaultHostname =
                        firstNonNull(sp.hostname(), ctx.config().virtualHost().defaultHostname());
                final AuthnRequest request = createAuthRequest(idp, defaultHostname);
                final MessageContext<AuthnRequest> messageContext = new MessageContext<>();
                messageContext.setMessage(request);
                return new MessageContextAndIdpConfig(messageContext, idp);
            }).thenCompose(arg -> {
                return ssoHandler.beforeInitiatingSso(ctx, req, arg.messageContext, arg.idpConfig)
                                 .thenApply(unused -> arg);
            }).thenApplyAsync(arg -> {
                final SAMLBindingContext bindingContext =
                        arg.messageContext.getSubcontext(SAMLBindingContext.class);
                final String relayState = bindingContext != null ? bindingContext.getRelayState() : null;

                // Support HTTP Redirect and HTTP POST binding protocols when sending
                // an authentication request.
                final SamlEndpoint endpoint = arg.idpConfig.ssoEndpoint();
                try {
                    if (endpoint.bindingProtocol() == SamlBindingProtocol.HTTP_REDIRECT) {
                        return responseWithLocation(toRedirectionUrl(
                                arg.messageContext.getMessage(),
                                endpoint.toUriString(), SAML_REQUEST,
                                signingCredential, sp.signatureAlgorithm(),
                                relayState));
                    } else {
                        // signing can incur a blocking call
                        final String value = toSignedBase64(
                                arg.messageContext.getMessage(),
                                signingCredential,
                                sp.signatureAlgorithm());
                        final HttpData body = getSsoForm(endpoint.toUriString(),
                                                         SAML_REQUEST, value,
                                                         relayState);
                        return HttpResponse.of(HttpStatus.OK, MediaType.HTML_UTF_8,
                                               body);
                    }
                } catch (SamlException e) {
                    return fail(ctx, e);
                }
            }, ctx.blockingTaskExecutor()).exceptionally(e -> fail(ctx, e)));
        }));
    }
A decorator which initiates an authentication request to the remote identity provider if the request is
not authenticated.
saml/src/main/java/com/linecorp/armeria/server/saml/SamlDecorator.java