Authentication Tree Redirect to IDP

This topic contains 2 replies, has 2 voices, and was last updated by  vlanglois 1 month, 3 weeks ago.

  • Author
    Posts
  • #23430
     vlanglois 
    Participant

    I have a use case where we need to redirect a user to an IDP based on the input provided at authn time.

    Basically, a user inputs something along the lines of user@domain.com.

    Input is sanitized, and then an LDAP fetch is done on an attribute containing a URL to its associated IDP provider.

    I was able to use this node to achieve the LDAP attribute fetch: https://github.com/ForgeRock/get-profile-attributes-node

    However, now the last piece of the puzzle is to actually redirect the user to the fetched URL. I tried using a simple window.location.href/replace in a scripted decision node, but the code is executed server side, so no dice. The redirect has to happen client side.

    I am currently attempting to make this node work: https://github.com/ForgeRock/client-script-auth-tree-node

    However, I am having perhaps some compatibility problems? When I include this node in WEB-INF/lib, and restart Tomcat, this will appear in debug logs:

    org.forgerock.http.servlet.HttpFrameworkServlet:10/10/2018 09:03:11:029 PM UTC: Thread[https-jsse-nio-8443-exec-85,5,main]: TransactionId[d9dbad54-6204-4e40-9342-92cb1e54665f-78]
    ERROR: RuntimeException caught
    java.lang.IllegalStateException: Exception from invocation expected to be handled by promise
    at org.forgerock.json.resource.AnnotatedMethod.invoke(AnnotatedMethod.java:100)
    at org.forgerock.json.resource.AnnotatedMethod.invoke(AnnotatedMethod.java:65)
    at org.forgerock.json.resource.AnnotationCollectionInstance.handleRead(AnnotationCollectionInstance.java:51)
    at org.forgerock.json.resource.FilterChain$Cursor.handleRead(FilterChain.java:105)
    at org.forgerock.json.resource.Resources$CollectionInstanceIdContextFilter.filterRead(Resources.java:520)
    at org.forgerock.json.resource.FilterChain$Cursor.handleRead(FilterChain.java:103)
    at org.forgerock.json.resource.FilterChain.handleRead(FilterChain.java:252)
    at org.forgerock.json.resource.Router.handleRead(Router.java:330)
    at org.forgerock.openam.core.rest.sms.tree.DescribedGeneralActionsHandler.handleRead(DescribedGeneralActionsHandler.java:87)
    at org.forgerock.json.resource.FilterChain$Cursor.handleRead(FilterChain.java:105)
    at org.forgerock.authz.filter.crest.AuthorizationFilters$AuthorizationFilter.lambda$filterRead$5(AuthorizationFilters.java:350)
    at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:252)
    at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:216)
    at org.forgerock.authz.filter.crest.AuthorizationFilters$AuthorizationFilter.filterRead(AuthorizationFilters.java:348)
    at org.forgerock.json.resource.FilterChain$Cursor.handleRead(FilterChain.java:103)
    at org.forgerock.json.resource.FilterChain.handleRead(FilterChain.java:252)
    at org.forgerock.json.resource.Router.handleRead(Router.java:330)
    at org.forgerock.openam.core.rest.sms.tree.SmsRouteTree.handleRead(SmsRouteTree.java:437)
    at org.forgerock.json.resource.Router.handleRead(Router.java:330)
    at org.forgerock.openam.core.rest.sms.tree.SmsRouteTree.handleRead(SmsRouteTree.java:437)
    at org.forgerock.json.resource.Router.handleRead(Router.java:330)
    at org.forgerock.openam.core.rest.sms.tree.SmsRouteTree.handleRead(SmsRouteTree.java:437)
    at org.forgerock.json.resource.Router.handleRead(Router.java:330)
    at org.forgerock.openam.core.rest.sms.tree.SmsRouteTree.handleRead(SmsRouteTree.java:437)
    at org.forgerock.openam.core.rest.sms.SmsRequestHandler.handleRead(SmsRequestHandler.java:961)
    at org.forgerock.json.resource.Router.handleRead(Router.java:330)
    at org.forgerock.json.resource.FilterChain$Cursor.handleRead(FilterChain.java:105)
    at org.forgerock.authz.filter.crest.AuthorizationFilters$AuthorizationFilter.lambda$filterRead$5(AuthorizationFilters.java:350)
    at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:252)
    at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:216)
    at org.forgerock.authz.filter.crest.AuthorizationFilters$AuthorizationFilter.filterRead(AuthorizationFilters.java:348)
    at org.forgerock.json.resource.FilterChain$Cursor.handleRead(FilterChain.java:103)
    at org.forgerock.json.resource.FilterChain.handleRead(FilterChain.java:252)
    at org.forgerock.json.resource.FilterChain$Cursor.handleRead(FilterChain.java:105)
    at org.forgerock.openam.rest.fluent.AuditFilter.filterRead(AuditFilter.java:187)
    at org.forgerock.openam.rest.fluent.AuditFilterWrapper.filterRead(AuditFilterWrapper.java:82)
    at org.forgerock.json.resource.FilterChain$Cursor.handleRead(FilterChain.java:103)
    at org.forgerock.openam.rest.fluent.CrestLoggingFilter.filterRead(CrestLoggingFilter.java:158)
    at org.forgerock.json.resource.FilterChain$Cursor.handleRead(FilterChain.java:103)
    at org.forgerock.openam.rest.ContextFilter.filterRead(ContextFilter.java:79)
    at org.forgerock.json.resource.FilterChain$Cursor.handleRead(FilterChain.java:103)
    at org.forgerock.openam.rest.AuthenticationEnforcer.filterRead(AuthenticationEnforcer.java:174)
    at org.forgerock.json.resource.FilterChain$Cursor.handleRead(FilterChain.java:103)
    at org.forgerock.json.resource.FilterChain.handleRead(FilterChain.java:252)
    at org.forgerock.json.resource.Router.handleRead(Router.java:330)
    at org.forgerock.json.resource.FilterChain$Cursor.handleRead(FilterChain.java:105)
    at org.forgerock.openam.rest.ContextFilter.filterRead(ContextFilter.java:79)
    at org.forgerock.json.resource.FilterChain$Cursor.handleRead(FilterChain.java:103)
    at org.forgerock.json.resource.FilterChain.handleRead(FilterChain.java:252)
    at org.forgerock.json.resource.InternalConnection.readAsync(InternalConnection.java:81)
    at org.forgerock.json.resource.http.RequestRunner.visitReadRequest(RequestRunner.java:279)
    at org.forgerock.json.resource.http.RequestRunner.visitReadRequest(RequestRunner.java:82)
    at org.forgerock.json.resource.Requests$ReadRequestImpl.accept(Requests.java:583)
    at org.forgerock.json.resource.http.RequestRunner.handleResult(RequestRunner.java:128)
    at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:252)
    at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:241)
    at org.forgerock.json.resource.http.HttpAdapter.doRequest(HttpAdapter.java:711)
    at org.forgerock.json.resource.http.HttpAdapter.doRead(HttpAdapter.java:368)
    at org.forgerock.json.resource.http.HttpAdapter.handle(HttpAdapter.java:273)
    at org.forgerock.http.handler.Handlers$HandlerDescribableAsDescribableHandler.handle(Handlers.java:146)
    at org.forgerock.http.filter.OptionsFilter.filter(OptionsFilter.java:69)
    at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53)
    at org.forgerock.http.routing.Router.handle(Router.java:100)
    at org.forgerock.openam.rest.RealmContextFilter.filter(RealmContextFilter.java:80)
    at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53)
    at org.forgerock.http.routing.Router.handle(Router.java:100)
    at org.forgerock.http.routing.Router.handle(Router.java:100)
    at org.forgerock.openam.rest.RealmRoutingFactory$ChfRealmRouter.handle(RealmRoutingFactory.java:140)
    at org.forgerock.http.routing.Router.handle(Router.java:100)
    at org.forgerock.openam.rest.RealmRoutingFactory$ChfRealmRouter.handle(RealmRoutingFactory.java:140)
    at org.forgerock.http.handler.Handlers$UndescribedAsDescribableHandler.handle(Handlers.java:179)
    at org.forgerock.openam.rest.RealmRoutingFactory$HostnameFilter.filter(RealmRoutingFactory.java:117)
    at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53)
    at org.forgerock.http.routing.Router.handle(Router.java:100)
    at org.forgerock.http.routing.Router.handle(Router.java:100)
    at org.forgerock.openam.rest.CsrfFilter.filter(CsrfFilter.java:88)
    at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53)
    at org.forgerock.http.routing.ResourceApiVersionRoutingFilter.filter(ResourceApiVersionRoutingFilter.java:59)
    at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53)
    at org.forgerock.caf.authentication.framework.AuthenticationFramework.grantAccess(AuthenticationFramework.java:188)
    at org.forgerock.caf.authentication.framework.AuthenticationFramework.lambda$onValidateRequestSuccess$1(AuthenticationFramework.java:181)
    at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:252)
    at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:241)
    at org.forgerock.caf.authentication.framework.AuthenticationFramework.validateRequest(AuthenticationFramework.java:144)
    at org.forgerock.caf.authentication.framework.AuthenticationFramework.processMessage(AuthenticationFramework.java:134)
    at org.forgerock.caf.authentication.framework.AuthenticationFilter.filter(AuthenticationFilter.java:84)
    at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53)
    at org.forgerock.openam.http.GuiceHandler.handle(GuiceHandler.java:51)
    at org.forgerock.openam.http.HttpRoute$6.handle(HttpRoute.java:206)
    at org.forgerock.http.routing.Router.handle(Router.java:100)
    at org.forgerock.openam.dpro.session.ProofOfPossessionTokenFilter.filter(ProofOfPossessionTokenFilter.java:88)
    at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53)
    at org.forgerock.http.swagger.OpenApiRequestFilter.filter(OpenApiRequestFilter.java:63)
    at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53)
    at org.forgerock.openam.http.ApiDescriptorFilter.filter(ApiDescriptorFilter.java:139)
    at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53)
    at org.forgerock.openam.http.OpenAMHttpApplication$1.filter(OpenAMHttpApplication.java:74)
    at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53)
    at org.forgerock.http.filter.TransactionIdInboundFilter.filter(TransactionIdInboundFilter.java:75)
    at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53)
    at org.forgerock.http.servlet.HttpFrameworkServlet.service(HttpFrameworkServlet.java:254)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.forgerock.openam.rest.ProtocolVersionFilter.doFilter(ProtocolVersionFilter.java:65)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.forgerock.openam.validation.ResponseValidationFilter.doFilter(ResponseValidationFilter.java:59)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.forgerock.openam.headers.SetHeadersFilter.doFilter(SetHeadersFilter.java:80)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at com.sun.identity.setup.AMSetupFilter.doFilter(AMSetupFilter.java:112)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.forgerock.openam.audit.context.AuditContextFilter.doFilter(AuditContextFilter.java:46)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
    Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.forgerock.json.resource.AnnotatedMethod.invoke(AnnotatedMethod.java:96)
    … 138 more
    Caused by: java.lang.IllegalArgumentException: Unsupported node type UsernameCollectorNode
    at org.forgerock.openam.auth.trees.engine.NodeFactory.getOutcomeProvider(NodeFactory.java:173)
    at org.forgerock.openam.auth.trees.engine.NodeFactory.getNodeOutcomes(NodeFactory.java:199)
    at org.forgerock.openam.core.rest.sms.AuthTreesCollectionProvider.read(AuthTreesCollectionProvider.java:319)
    … 143 more

    I am currently running OpenAM 6.0.0.2:

    com.iplanet.am.version=ForgeRock Access Management 6.0.0.2 Build 3a1761ce2e (2018-June-12 22:40)

    I have used the master branch pom.xml file for building the node:

    https://github.com/ForgeRock/client-script-auth-tree-node/blob/master/pom.xml

    Aside from perhaps troubleshooting this script, is there another way of doing a 302 towards an URL in an authn tree?

    #23433
     James Phillpotts 
    Moderator

    To perform a redirect, you should return a com.sun.identity.authentication.spi.RedirectCallback. If you’re expecting to return back to the tree from the page you redirect off to, you should be sure to do redirectCallback.setTrackingCookie(true).

    If you are a customer/partner with access to the “am-external” source repo, you can find some example usage here: https://stash.forgerock.org/projects/OPENAM/repos/am-external/browse/openam-auth-trees/auth-nodes/src/main/java/org/forgerock/openam/auth/nodes/oauth?at=refs%2Fheads%2Freleases%2F6.0.0.4

    #23506
     vlanglois 
    Participant

    Hi James,

    Thank you for the reply. I am able to do a redirect to an IDP now, based on the sample code you linked.

    I made sure to include the line

    redirectCallback.setTrackingCookie(true)

    in order to come back to my tree after a successful authentication at the IDP.

    My problem now is that I seem to be unable to leverage this tracking cookie correctly. Once I have authenticated at the IDP, I would need to have a successful URL on that end to come back to the OpenAM authn tree. Is that URL the regular login URL? Do I have to specify an URL parameter of some sort?

    Do I have to include some special logic in my authnetication tree to capture this cookie and proceed from there, or does the cookie really point back to where I left off in the first place? This part seems a bit fuzzy/magical to me still.

    Thanks again,

    Vincent

Viewing 3 posts - 1 through 3 (of 3 total)

You must be logged in to reply to this topic.

©2018 ForgeRock - we provide an identity and access platform to secure every online relationship for the enterprise market, educational sector and even entire countries. Click to view our privacy policy and terms of use.

Log in with your credentials

Forgot your details?