Pac4j Zeppelin - KeyCloak Integration - Logout Forbidden and Other Errors

606 views
Skip to first unread message

Srinivasan Anand

unread,
Dec 5, 2021, 7:08:28 AM12/5/21
to Pac4j users mailing list
Hi,

We have been trying to solve this for quite some days. 

This is what we have been trying to achieve and where we have got stuck.
  • Use Pac4j(4.0.0) - shiro for Zeppelin Integration
    • 4.x has been chosen for the Java 52 compiled version. 
    • Since we didn't have the Zeppelin compiled from our end, we chose to include the needed libraries as and when there was an error 
      • Overall, we included the below ones. 
        • pac4j-core-4.0.0.jar
        • pac4j-oidc-4.0.0.jar
        • buji-pac4j-5.0.1.jar
        • common-2.37.jar
        • content-type-2.1.jar
        • javax.mail-api-1.6.2.jar
        • lang-tag-1.5.jar
        • oauth2-oidc-sdk-7.5.jar
  • The Shiro.ini file contents - This below format was chosen, so that this can be reused to append the client creds and other default urls for other Zeppelin Instances as well
    • [urls]
    • /api/version = anon
    • /api/callback = callbackFilter
    • /api/log/** = anon
    • /api/login/logout = logoutFilter
    • /** = oidcSecurityFilter

    • [main]
    • sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager

    • securityManager.sessionManager = $sessionManager
    • securityManager.sessionManager.globalSessionTimeout = 86400000

    • ### OIDC Pac4j Config
    • oidcConfig = org.pac4j.oidc.config.OidcConfiguration
    • oidcConfig.withState = false
    • oidcConfig.discoveryURI = https://........well-known/openid-configuration
    • oidcConfig.clientAuthenticationMethodAsString = client_secret_basic
    • oidcClient = org.pac4j.oidc.client.OidcClient
    • #oidcConfig.useNonce = true
    • oidcClient.configuration = $oidcConfig

    • ### Pac4J Client Details
    • clients = org.pac4j.core.client.Clients
    • clients.clients = $oidcClient

    • ### Pac4j Config
    • config = org.pac4j.core.config.Config
    • config.clients = $clients

    • #Only allow access to specific users
    • usernameAuthorizer = org.pac4j.core.authorization.authorizer.UsernameAuthorizer
    • config.authorizers = username:$usernameAuthorizer

    • ### Pac4jRealm and SecurityFilter
    • pac4jRealm = io.buji.pac4j.realm.Pac4jRealm
    • pac4jRealm.principalNameAttribute = email
    • pac4jSubjectFactory = io.buji.pac4j.subject.Pac4jSubjectFactory
    • securityManager.subjectFactory = $pac4jSubjectFactory
    • securityManager.realms = $pac4jRealm

    • ### SecurityFilter Configs
    • oidcSecurityFilter = io.buji.pac4j.filter.SecurityFilter
    • oidcSecurityFilter.config = $config
    • oidcSecurityFilter.clients = oidcClient
    • oidcSecurityFilter.authorizers = username

    • ### Ajax Resolvers
    • ajaxRequestResolver = org.pac4j.core.http.ajax.DefaultAjaxRequestResolver
    • ajaxRequestResolver.addRedirectionUrlAsHeader = true
    • oidcClient.ajaxRequestResolver = $ajaxRequestResolver

    • ### Callback Filters
    • callbackFilter = io.buji.pac4j.filter.CallbackFilter
    • callbackFilter.config = $config

    • customCallbackLogic = org.pac4j.core.engine.ForceDefaultURLCallbackLogic
    • callbackFilter.callbackLogic = $customCallbackLogic

    • ### Logout Filter
    • logoutFilter = io.buji.pac4j.filter.LogoutFilter
    • logoutFilter.localLogout = false
    • logoutFilter.centralLogout = true
    • logoutFilter.config = $config

    • ### Individual Configs
    • oidcConfig.clientId = xxxxxx
    • oidcConfig.secret = xxxxxx
    • logoutFilter.defaultUrl = https://xxxxxxx...
    • callbackFilter.defaultUrl = https://xxxxxxx...
    • clients.callbackUrl = https://xxxxxxx/api/callback
    • usernameAuthorizer.elements = xxxxx,wwwww
Since the usecase was pretty much the same, we pretty much followed this link for the integration

The Login(callbackFilter.callbackLogic) and user restriction(usernameAuthorizer = org.pac4j.core.authorization.authorizer.UsernameAuthorizer) are working fine. 

The Logout seems to be Herculean task. 

The Logout seems to be triggered as an Ajax POST through /api/login/logout. 
  • At first, it was getting the forbidden error
    • OidcActionLogoutBuilder - 
      • ajaxRequestResolver.isAjax(context)
        • ==> throw ForbiddenAction.INSTANCE;
      • So commented this out
  • After commenting, a 302 redirection(SEE_OTHER) Action was getting returned with location set to the IDP logout URL appended with the post_redirect_uri and id_token_hint
    • return Optional.of(RedirectionActionHelper.buildRedirectUrlAction(context, logoutRequest.toURI().toString()));
  • This was returning a CORS error from the IDP using KeyCloak
And this is were we are stuck. 

We have some questions 
  • Why was an AJAX post request forbidden?
  • What was supposed to be the way out for logout, if the AJAX post request was forbidden
  • How is the IDP supposed to behave on getting a cross origin request
  • The IDP people claim that the logout URL should not be 302 redirection through AJAX, rather the window.location needs to be invoked to the IDP Logout location
    • In which case, we need to change the Zeppelin Frontend to catch this in the post success/failure handler and then invoke the window.location 
      • In which case, will there be any custom Session/Cookies clearance we might need to do?
  • Or is there any flow which I should be using and have missed out?
These are some of the questions. 

Please help. 

Sandy

Srinivasan Anand

unread,
Dec 6, 2021, 10:05:11 AM12/6/21
to Pac4j users mailing list
Hi Anyone ? 

This is a blocker for us. Any good pointer? 

Srinivasan Anand

unread,
Dec 9, 2021, 1:21:02 PM12/9/21
to Pac4j users mailing list
Hi.... Any help out here? 

Jerome, could you please check this and give us a good direction .. 

Jérôme LELEU

unread,
Dec 10, 2021, 2:39:49 AM12/10/21
to Srinivasan Anand, Pac4j users mailing list
Hi,

I assume that Zeppelin calls the pac4j OIDC logout as an AJAX request.

We forbid the AJAX request to notify you that we won't perform the logout request and that the logout URL is in the Location header and that it's up to you to call it.
You can change that behavior of course by providing your own OidcLogoutActionBuilder.

If you use AJAX requests, indeed, you may face CORS issues.

The whole logout process may involve a 302 redirection at the end, but you may not need it. Contacting the IdP to delete the SSO session may be sufficient.

So it's better to send the logout URL in the browser (window.location) than as an AJAX request, but it may be enough.

Thanks.
Best regards,
Jérôme



--
You received this message because you are subscribed to the Google Groups "Pac4j users mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pac4j-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pac4j-users/48b7bdae-e409-47b5-b7d2-fe25a57446f2n%40googlegroups.com.

Srinivasan Anand

unread,
Dec 10, 2021, 5:32:57 AM12/10/21
to Pac4j users mailing list
Thank you for the direction. 

One thing is, even if we did implement our own OidcLogoutActionBuilder logic, the response again goes back to the Ajax post request origin and from there, it will be a 302 redirection(which will response with the CORS) 

So, in order to achieve this, I think we have 2 options
  • solve the CORS issue on the IDP side, with the AJAX sent to the logout endpoint
  • modify the frontend to catch the post response and do a window.location to the logout URL
Ok. These options were there with us. Just wanted to ensure that we didn't miss out any other possibilities through which these can be solved. 

BR
Sandy

Jérôme LELEU

unread,
Dec 10, 2021, 10:16:29 AM12/10/21
to Srinivasan Anand, Pac4j users mailing list
Hi,

You're right. It starts with a 302 to the IdP logout URL.

Both solutions can be implemented.

Thanks.
Best regards,
Jérôme


ssh terminus

unread,
Aug 30, 2023, 5:19:35 AM8/30/23
to Please use https://stackoverflow.com with the pac4j tag
Hi, can I get code for  ForceDefaultURLCallbackLogic.java and  UsernameAuthorizer.java or your pac4j-core-4.0.0.jar file?

Thank you so much!
Reply all
Reply to author
Forward
0 new messages