Error authenticating users with SAML artifact binding using a vertx and pac4j application as SP and simplesamlphp as IdP

28 views Asked by At

I have an application with vertx and pac4j acting as SP. I want to authenticate users with SAML artifact binding. As IdP I am using simplesamlphp. When the user authenticates to the IdP and the IdP sends the SAMLart to the SP I get the following error. Does anyone know how I can fix this error or what's wrong with my code? Do I have to add any extra configuration to the simplesamlphp IdP other than what is listed in the official documentation?:

VERT.X PAC4J DEMO 20:42:16.118 [vert.x-eventloop-thread-1] ERROR io.vertx.ext.web.RoutingContext - Unhandled exception in router org.pac4j.core.exception.TechnicalException: org.pac4j.saml.exceptions.SAMLException: Error decoding SAML message at org.pac4j.vertx.handler.impl.CallbackHandler.lambda$handle$1(CallbackHandler.java:68) at io.vertx.core.impl.future.FutureImpl$4.onFailure(FutureImpl.java:188) at io.vertx.core.impl.future.FutureBase.lambda$emitFailure$1(FutureBase.java:75) at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173) at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166) at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569) at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.base/java.lang.Thread.run(Thread.java:1589) Caused by: org.pac4j.saml.exceptions.SAMLException: Error decoding SAML message at org.pac4j.saml.sso.artifact.SAML2ArtifactBindingMessageReceiver.getDecoder(SAML2ArtifactBindingMessageReceiver.java:56) at org.pac4j.saml.profile.impl.AbstractSAML2MessageReceiver.receiveMessage(AbstractSAML2MessageReceiver.java:49) at org.pac4j.saml.sso.impl.SAML2WebSSOProfileHandler.receive(SAML2WebSSOProfileHandler.java:35) at org.pac4j.saml.credentials.extractor.SAML2CredentialsExtractor.receiveLogin(SAML2CredentialsExtractor.java:71) at org.pac4j.saml.credentials.extractor.SAML2CredentialsExtractor.extract(SAML2CredentialsExtractor.java:66) at org.pac4j.core.client.BaseClient.retrieveCredentials(BaseClient.java:71) at org.pac4j.core.client.IndirectClient.getCredentials(IndirectClient.java:145) at org.pac4j.core.engine.DefaultCallbackLogic.perform(DefaultCallbackLogic.java:75) at org.pac4j.vertx.handler.impl.CallbackHandler.lambda$handle$0(CallbackHandler.java:60) at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$1(ContextImpl.java:190) at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:276) at io.vertx.core.impl.ContextImpl.lambda$internalExecuteBlocking$2(ContextImpl.java:209) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ... 2 common frames omitted Caused by: org.opensaml.messaging.decoder.MessageDecodingException: org.opensaml.messaging.decoder.MessageDecodingException: Fatal error decoding or resolving inbound artifact at org.pac4j.saml.sso.artifact.SAML2ArtifactBindingDecoder.doDecode(SAML2ArtifactBindingDecoder.java:88) at org.opensaml.messaging.decoder.AbstractMessageDecoder.decode(AbstractMessageDecoder.java:65) at org.pac4j.saml.sso.artifact.SAML2ArtifactBindingMessageReceiver.getDecoder(SAML2ArtifactBindingMessageReceiver.java:54) ... 15 common frames omitted Caused by: org.opensaml.messaging.decoder.MessageDecodingException: Fatal error decoding or resolving inbound artifact at org.pac4j.saml.transport.Pac4jHTTPArtifactDecoder.processArtifact(Pac4jHTTPArtifactDecoder.java:520) at org.pac4j.saml.transport.Pac4jHTTPArtifactDecoder.doDecode(Pac4jHTTPArtifactDecoder.java:192) at org.opensaml.messaging.decoder.AbstractMessageDecoder.decode(AbstractMessageDecoder.java:65) at org.pac4j.saml.transport.Pac4jHTTPArtifactDecoder.decode(Pac4jHTTPArtifactDecoder.java:158) at org.pac4j.saml.sso.artifact.SAML2ArtifactBindingDecoder.doDecode(SAML2ArtifactBindingDecoder.java:81) ... 17 common frames omitted Caused by: net.shibboleth.shared.component.UninitializedComponentException: Unidentified Component has not yet been initialized and cannot be used. at net.shibboleth.shared.component.AbstractInitializableComponent.ifNotInitializedThrowUninitializedComponentException(AbstractInitializableComponent.java:81) at net.shibboleth.shared.component.AbstractInitializableComponent.checkComponentActive(AbstractInitializableComponent.java:110) at org.opensaml.messaging.handler.AbstractMessageHandler.invoke(AbstractMessageHandler.java:82) at org.opensaml.soap.client.http.AbstractPipelineHttpSOAPClient.send(AbstractPipelineHttpSOAPClient.java:178) at org.pac4j.saml.sso.artifact.SAML2ArtifactBindingDecoder$1.send(SAML2ArtifactBindingDecoder.java:65) at org.pac4j.saml.transport.Pac4jHTTPArtifactDecoder.dereferenceArtifact(Pac4jHTTPArtifactDecoder.java:553) at org.pac4j.saml.transport.Pac4jHTTPArtifactDecoder.processArtifact(Pac4jHTTPArtifactDecoder.java:514) ... 21 common frames omitted

The vertx code I am using for the SP is as follows:

public class MainVerticle extends AbstractVerticle {

  @Override
  public void start(Promise<Void> startPromise) throws Exception {

    HttpServerOptions serverOptions = new HttpServerOptions().setMaxFormAttributeSize(65536);
    HttpServer server = vertx.createHttpServer(serverOptions);
    Router router = Router.router(vertx);
    LocalSessionStore vertxSessionStore = LocalSessionStore.create(vertx);
    SessionStore sessionStore = new VertxSessionStore(vertxSessionStore);
    Pac4jAuthProvider authProvider = new Pac4jAuthProvider();
    SessionHandler sessionHandler = SessionHandler.create(vertxSessionStore);

    router.get("/login").handler(StaticHandler.create("src/main/resources/static/login.html"));

    SAML2Client saml2Client = this.saml2Client();
    Config config = new Config("http://localhost:8888/callback",saml2Client);

    router.route().handler(sessionHandler);
    
    SecurityHandlerOptions options = new SecurityHandlerOptions().setClients("SAML2Client");
    router.route("/msg.html").handler(new SecurityHandler(vertx, sessionStore, config, authProvider,options));
    router.get("/msg.html").handler(rc ->{
      rc.response().putHeader(CONTENT_TYPE, TEXT_HTML);
      rc.next();
    });
    router.get("/msg.html").handler(generateMSG(vertx));

    CallbackHandlerOptions callbackHandlerOptions = new CallbackHandlerOptions()
                .setDefaultUrl("/")
                .setMultiProfile(true);
    CallbackHandler callbackHandler = new CallbackHandler(vertx, sessionStore, config, callbackHandlerOptions);
    router.get("/callback").handler(callbackHandler);
    router.post("/callback").handler(BodyHandler.create().setMergeFormAttributes(true));
    router.post("/callback").handler(callbackHandler);

    router.get("/logout").handler(SingleLogouthandler(vertx, config, sessionStore));

    server.requestHandler(router).listen(8888, http -> {
      if (http.succeeded()) {
            startPromise.complete();
            System.out.println("HTTP server started on port 8888");
          } else {
            startPromise.fail(http.cause());
          }
    });
  }

  private SAML2Client saml2Client(){
    SAML2Configuration cfg = new SAML2Configuration("samlConfig/samlKeystore.jks", 
                                    "pac4j-demo-passwd", 
                                    "pac4j-demo-passwd", 
                                    "samlConfig/idp-metadata.xml");

    cfg.setAuthnRequestBindingType(SAMLConstants.SAML2_POST_BINDING_URI);
    cfg.setResponseBindingType(SAMLConstants.SAML2_ARTIFACT_BINDING_URI);
    cfg.setServiceProviderEntityId("http://localhost:8888/callback?client_name=SAML2Client");
    cfg.setServiceProviderMetadataPath(new File("target", "sp-metadata.xml").getAbsolutePath());
    return new SAML2Client(cfg);
  }

  private Handler<RoutingContext> SingleLogouthandler(Vertx vertx, Config config, SessionStore sessionStore){
    LogoutHandlerOptions logoutOptions = new LogoutHandlerOptions()
        .setCentralLogout(true)
        .setLocalLogout(true)
        .setDefaultUrl("http://localhost:8888/login");
    return new LogoutHandler(vertx, sessionStore, logoutOptions, config);
  }

  private Handler<RoutingContext> generateMSG(Vertx vertx){
        HandlebarsTemplateEngine engine = HandlebarsTemplateEngine.create(vertx);
        return rc -> {
            engine.render(rc.data(), "templates/msg.hbs", res -> {
                if (res.succeeded()) {
                    rc.response().end(res.result());
                  } else {
                    rc.fail(res.cause());
                  }
            });
        };
  }

}
0

There are 0 answers