roles management with pac4j oidc + keycloak/shiro

243 views
Skip to first unread message

Dali

unread,
Apr 15, 2019, 8:12:34 AM4/15/19
to Pac4j users mailing list
Hello,

We have a working setup with Pac4j OIDC, Shiro and keyclaok to secure a Zeppelin server.
I'm trying to add roles management in my zeppelin but i didn't succeed to retrieve keycloak roles.
here is my shiro.ini :

roleAdminAuthGenerator = org.pac4j.core.authorization.generator.FromAttributesAuthorizationGenerator
....


oidcClient = org.pac4j.oidc.client.OidcClient
oidcClient.configuration = $oidcConfig
oidcClient.authorizationGenerator = $roleAdminAuthGenerator

pac4jRealm = io.buji.pac4j.realm.Pac4jRealm
pac4jRealm.principalNameAttribute=preferred_username
pac4jSubjectFactory = io.buji.pac4j.subject.Pac4jSubjectFactory
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
securityManager.realms = $pac4jRealm
securityManager.subjectFactory = $pac4jSubjectFactory
securityManager.sessionManager = $sessionManager
securityManager.sessionManager.globalSessionTimeout = 86400000

requireRoleAdmin = org.pac4j.core.authorization.authorizer.RequireAnyRoleAuthorizer
requireRoleAdmin.elements = admin_role
requireRoleUser = org.pac4j.core.authorization.authorizer.RequireAnyRoleAuthorizer
requireRoleUser.elements = admin_role, user_role

....

config = org.pac4j.core.config.Config
config.clients = $clients
config.authorizers = admin:$requireRoleAdmin,user:$requireRoleUser

....

oidcSecurityFilterAdmin = io.buji.pac4j.filter.SecurityFilter
oidcSecurityFilterAdmin.config = $config
oidcSecurityFilterAdmin.clients = oidcClient
oidcSecurityFilterAdmin.authorizers = admin

...


But it seems that i'm not able to retrieve the roles configured in the keycloak side : {"status":"OK","message":"","body":{"principal":"myEmail","ticket":"myTicket","roles":"[]"}}. I'm getting always an empty array
Is there something missing or wrong ?

Thank you in advance
King regards,
Dali


Jérôme LELEU

unread,
Apr 16, 2019, 2:11:48 AM4/16/19
to Dali, Pac4j users mailing list

--
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.
For more options, visit https://groups.google.com/d/optout.

Dali

unread,
Apr 16, 2019, 5:05:42 AM4/16/19
to Pac4j users mailing list
Hi Jérôme,

Thank you very much for the reply.
As i posted in an another post in the development mailing list i saw the KeycloakRolesAuthorizationGenerator but i couldn't use it instead of FromAttributesAuthorizationGenerator (i can't instantiate it)

roleAdminAuthGenerator = org.pac4j.oidc.authorization.generator.KeycloakRolesAuthorizationGenerator
roleAdminAuthGenerator.clientId = *******

...

There is no default constructor in the KeycloakRolesAuthorizationGenerator component


regards,
Dali
To unsubscribe from this group and stop receiving emails from it, send an email to pac4j...@googlegroups.com.

Jérôme LELEU

unread,
Apr 16, 2019, 6:26:55 AM4/16/19
to Dali, Pac4j users mailing list
Hi,

Indeed, it's not compatible with Shiro. We need to add an empty constructor and the appropriate setter.
Thanks.
Best regards,
Jérôme


To unsubscribe from this group and stop receiving emails from it, send an email to pac4j-users...@googlegroups.com.

Jérôme LELEU

unread,
Apr 17, 2019, 8:33:23 AM4/17/19
to Dali, Pac4j users mailing list
Hi,

Can you try with the version 3.7.0-SNAPSHOT?
Thanks.
Best regards,
Jérôme



Le mar. 16 avr. 2019 à 11:05, Dali <moh...@fifty-five.com> a écrit :
To unsubscribe from this group and stop receiving emails from it, send an email to pac4j-users...@googlegroups.com.

Dali

unread,
Apr 17, 2019, 12:08:33 PM4/17/19
to Pac4j users mailing list
Hi Jérôme,

All good ... it works !
Thank you very much for your help.


King regards,
Dali

esirem malaysia

unread,
Nov 7, 2019, 11:51:32 AM11/7/19
to Pac4j users mailing list
Hi Dali and Jérôme LELEU, 

I 'm trying to retrieve roles from Keycloak users to Zeppelin Server which uses Shiro Authentification but I got this error even if I use the newest following pac4j version (buji-pac4j-4.1.1, pac4j-oidc-3.8.3, pac4j-core-3.8.3) and the new Keycloak classes implemented by Jérôme LELEU into pac4j-oidc : 

INFO [2019-11-07 14:58:30,866] ({main} ContextHandler.java[log]:2345) - Initializing Shiro environment
INFO [2019-11-07 14:58:30,867] ({main} EnvironmentLoader.java[initEnvironment]:133) - Starting Shiro environment initialization.
ERROR [2019-11-07 14:58:31,038] ({main} EnvironmentLoader.java[initEnvironment]:152) - Shiro environment initialization failed
java.lang.IllegalArgumentException: Line argument must contain a key and a value.  Only one string token was found.
at org.apache.shiro.config.Ini$Section.splitKeyValue(Ini.java:601)
at org.apache.shiro.config.Ini$Section.toMapProps(Ini.java:626)
at org.apache.shiro.config.Ini$Section.<init>(Ini.java:523)
at org.apache.shiro.config.Ini$Section.<init>(Ini.java:504)
at org.apache.shiro.config.Ini.addSection(Ini.java:361)
at org.apache.shiro.config.Ini.load(Ini.java:393)
at org.apache.shiro.config.Ini.load(Ini.java:295)
at org.apache.shiro.config.Ini.load(Ini.java:283)
at org.apache.shiro.web.env.IniWebEnvironment.convertPathToIni(IniWebEnvironment.java:355)
at org.apache.shiro.web.env.IniWebEnvironment.createIni(IniWebEnvironment.java:244)
at org.apache.shiro.web.env.IniWebEnvironment.getSpecifiedIni(IniWebEnvironment.java:185)
at org.apache.shiro.web.env.IniWebEnvironment.parseConfig(IniWebEnvironment.java:96)
at org.apache.shiro.web.env.IniWebEnvironment.init(IniWebEnvironment.java:69)
at org.apache.shiro.util.LifecycleUtils.init(LifecycleUtils.java:45)
at org.apache.shiro.util.LifecycleUtils.init(LifecycleUtils.java:40)
at org.apache.shiro.web.env.EnvironmentLoader.createEnvironment(EnvironmentLoader.java:313)
at org.apache.shiro.web.env.EnvironmentLoader.initEnvironment(EnvironmentLoader.java:139)
at org.apache.shiro.web.env.EnvironmentLoaderListener.contextInitialized(EnvironmentLoaderListener.java:58)
at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:957)
at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:552)
at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:922)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:364)
at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1497)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1459)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:852)
at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:278)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:545)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:138)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:117)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:168)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:138)
at org.eclipse.jetty.server.Server.start(Server.java:415)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:108)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113)
at org.eclipse.jetty.server.Server.doStart(Server.java:382)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.apache.zeppelin.server.ZeppelinServer.main(ZeppelinServer.java:241)

And so no access to Zeppelin interface. I tried 2 configurations, here it is.

1) In the case of using Oidc (pac4j-oidc) classes, I got this configuration in my shiro.ini : 

[main]
roleAdminAuthGenerator = org.pac4j.core.authorization.generator.FromAttributesAuthorizationGenerator

oidcConfig = org.pac4j.oidc.config.OidcConfiguration
oidcConfig.clientId = zeppelin-client
oidcConfig.secret = <SECRET>
oidcConfig.clientAuthenticationMethodAsString = client_secret_basic
oidcConfig.scope = openid
oidcConfig.useNonce = true
oidcConfig.responseType = code

oidcClient = org.pac4j.oidc.client.OidcClient
oidcClient.configuration = $oidcConfig
oidcClient.authorizationGenerator = $roleAdminAuthGenerator

clients = org.pac4j.core.client.Clients
clients.clients = $oidcClient

requireRoleAdmin = org.pac4j.core.authorization.authorizer.RequireAnyRoleAuthorizer
requireRoleAdmin.elements = admin_role

config = org.pac4j.core.config.Config
config.clients = $clients
config.authorizers = admin:$requireRoleAdmin

pac4jRealm = io.buji.pac4j.realm.Pac4jRealm
pac4jRealm.principalNameAttribute=preferred_username
pac4jSubjectFactory = io.buji.pac4j.subject.Pac4jSubjectFactory

### If caching of user is required then uncomment below lines
#cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
#securityManager.cacheManager = $cacheManager
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
securityManager.sessionManager = $sessionManager
securityManager.sessionManager.globalSessionTimeout = 86400000
securityManager.subjectFactory = $pac4jSubjectFactory
securityManager.realms = $pac4jRealm

oidcSecurityFilter = io.buji.pac4j.filter.SecurityFilter
oidcSecurityFilter.config = $config
oidcSecurityFilter.clients = oidcClient

logoutFilter = io.buji.pac4j.filter.LogoutFilter
logoutFilter.defaultUrl = http://localhost:8080
logoutFilter.localLogout = true
logoutFilter.centralLogout = true
logoutFilter.config = $config

callbackFilter = io.buji.pac4j.filter.CallbackFilter
callbackFilter.defaultUrl = http://localhost:8080
callbackFilter.config = $config

[urls]
/api/version = anon
/api/callback = callbackFilter
/** = oidcSecurityFilter
/api/login/logout = logoutFilter


> RESULT 1 : Can successfully login to zeppelin via Keycloak users contrary of using KeycloakOidc classes, BUT can't retrieve roles, the array is actually empty as Dali noticed in his last posts. Here what I've got : {"status":"OK","message":"","body":{"principal":"user1","ticket":"109144f3-2038-4922-b025-f1d4d8abd86a","roles":"[]"}}. So, I'm getting always an empty array and the Zeppelin logout API does not work also (which is another problem).

2) In the case of using KeycloakOidc (pac4j-oidc) classes as Jérôme LELEU recommended in this post, I got this configuration in my shiro.ini : 

[main]
roleAdminAuthGenerator = org.pac4j.oidc.authorization.generator.KeycloakRolesAuthorizationGenerator
roleAdminAuthGenerator.roleAttributes = admin_role

oidcConfig = org.pac4j.oidc.config.KeycloakOidcConfiguration
oidcConfig.clientId = zeppelin-client
oidcConfig.secret = <SECRET>
oidcConfig.realm = zeppelin
# base uri of keycloak. For instance `http://localhost:5000/auth`. This attribute is then concataned with **"/realms/"+realm+"/.well-known/openid-configuration"**
oidcConfig.baseUri = http://localhost:5000/auth
oidcConfig.useNonce = true
oidcConfig.clientAuthenticationMethodAsString = client_secret_basic

keycloakOidcClient = org.pac4j.oidc.client.KeycloakOidcClient
keycloakOidcClient.configuration = $oidcConfig
keycloakOidcClient.authorizationGenerator = $roleAdminAuthGenerator

clients = org.pac4j.core.client.Clients
clients.clients = $keycloakOidcClient

requireRoleAdmin = org.pac4j.core.authorization.authorizer.RequireAnyRoleAuthorizer
requireRoleAdmin.elements = admin_role
requireRoleUser = org.pac4j.core.authorization.authorizer.RequireAnyRoleAuthorizer
requireRoleUser.elements = admin_role, user_role

config = org.pac4j.core.config.Config
config.clients = $clients
config.authorizers = admin:$requireRoleAdmin,user:$requireRoleUser

pac4jRealm = io.buji.pac4j.realm.Pac4jRealm
pac4jRealm.principalNameAttribute = preferred_username
pac4jSubjectFactory = io.buji.pac4j.subject.Pac4jSubjectFactory

oidcSecurityFilter = io.buji.pac4j.filter.SecurityFilter
oidcSecurityFilter.config = $config
oidcSecurityFilter.clients = keycloakOidcClient

sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
#securityManager.realms = $pac4jRealm
securityManager.subjectFactory = $pac4jSubjectFactory
securityManager.sessionManager = $sessionManager
securityManager.sessionManager.globalSessionTimeout = 86400000

callbackFilter = io.buji.pac4j.filter.CallbackFilter
callbackFilter.defaultUrl = http://localhost:8080
callbackFilter.config = $config

logoutFilter = io.buji.pac4j.filter.LogoutFilter
logoutFilter.defaultUrl = http://localhost:8080
logoutFilter.localLogout = true
logoutFilter.centralLogout = true
logoutFilter.config = $config

[urls]
/api/version = anon
/api/callback = callbackFilter
/api/login/logout = logoutFilter
/** = oidcSecurityFilter


RESULT 2 : Cannot login to zeppelin via Keycloak and getting errors in logs as shown above. And so NO access to Zeppelin and Roles. With this configuration nothing works.

Can you please debug me on this point. And also does this admin_role and user_role needs to be configured in Keycloak as defined in this shiro.ini ? I think it is related to role based authorization, can you please tell me some information related to role based authorization ?
I will be grateful to have another point of view which can clear my actual issue. Thanks in advance.

Kind regards,
Esirem.
Reply all
Reply to author
Forward
0 new messages