I´m currently try to setup Shiro with Keycloak. I searched on the internet and found some shiro.ini settings for setup a OIDC Config with Keycloak. I´ve setup Shiro before without Keycloak authentication - everything was based on JDBC realm. I´m managing my permissions with Shiro. I have in my app some SQL tables (permission_role_object). Therefore I have those JDBC queries:
jdbcRealm.userRolesQuery = ...
jdbcRealm.permissionsQuery = ...
My question is, how can I have a relationship to my pac4jRealm (= Keycloak authentication) to my SQL table for the permissions? I guess I need also to add something in the shiro.ini:
pac4jRealm.userRolesQuery = ...
pac4jRealm.permissionsQuery = ...
This is my current shiro.ini
[main]
#### Session
sessionIdCookie=org.apache.shiro.web.servlet.SimpleCookie
#sessionIdCookie.path = /
sessionIdCookie.httpOnly = true
sessionIdCookie.name = sid
sessionIdCookie.domain = localhost
sessionIdCookie.maxAge=28800000
sessionIdCookie.secure = true
sessionIdCookie.sameSite = LAX
sessionManager=org.apache.shiro.web.session.mgt.DefaultWebSessionManager
sessionManager.sessionIdCookie=$sessionIdCookie
sessionManager.sessionIdCookieEnabled=true
securityManager.sessionManager=$sessionManager
# Session Timeout nach 8 Stunden
sessionManager.globalSessionTimeout= 28800000
sessionListener1= de.dpunkt.myaktion.util.MySessionListener1
sessionManager.sessionListeners=$sessionListener1
# Session validation = 5 minutes
sessionManager.sessionValidationInterval = 300000
#sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
#securityManager.sessionMode=native
sessionValidationScheduler=org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler
sessionValidationScheduler.interval = 60000
sessionValidationScheduler.sessionManager=$sessionManager
sessionManager.sessionValidationScheduler=$sessionValidationScheduler
sessionManager.deleteInvalidSessions=true
#sessionFactory=org.apache.shiro.session.mgt.OnlineSessionFactory
#sessionManager.sessionFactory=$sessionFactory
#securityManager.subjectDAO.sessionStorageEvaluator.sessionStorageEnabled = false
#Keycloack
oidcConfig = org.pac4j.oidc.config.OidcConfiguration
oidcConfig.withState = false
oidcConfig.discoveryURI = http://localhost:9009/auth/realms/myapp/.well-known/openid-configuration
oidcConfig.clientId = myapp
oidcConfig.secret = 112345679465456
oidcConfig.clientAuthenticationMethodAsString = client_secret_basic
oidcClient = org.pac4j.oidc.client.OidcClient
oidcClient.configuration = $oidcConfig
clients = org.pac4j.core.client.Clients
clients.callbackUrl = http://localhost:8080/api/callback
clients.clients = $oidcClient
pac4jRealm = io.buji.pac4j.realm.Pac4jRealm
pac4jRealm.principalNameAttribute = preferred_username
pac4jSubjectFactory = io.buji.pac4j.subject.Pac4jSubjectFactory
pac4jRealm.principalNameAttribute = preferred_username
securityManager.subjectFactory = $pac4jSubjectFactory
#usernameAuthorizer = myapp.util.UsernameAuthorizer
#usernameAuthorizer.elements = ${user1},${user2}
config = org.pac4j.core.config.Config
config.clients = $clients
#config.authorizers = username:$usernameAuthorizer
oidcSecurityFilter = io.buji.pac4j.filter.SecurityFilter
oidcSecurityFilter.config = $config
oidcSecurityFilter.clients = oidcClient
oidcSecurityFilter.authorizers = +username
# DataSource
ds = com.mysql.cj.jdbc.MysqlDataSource
ds.serverName = localhost
ds.user = root
ds.password = test1234
ds.databaseName = myapp
ds.useSSL = false
ds.serverTimezone = Europe/Berlin
# password hashing specification, put something big for hasIterations
sha512Matcher = org.apache.shiro.authc.credential.HashedCredentialsMatcher
sha512Matcher.hashAlgorithmName=SHA-512
sha512Matcher.hashIterations=1
# Configure JDBC realm datasource.
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.permissionsLookupEnabled = true
jdbcRealm.authenticationQuery = select password FROM user where UPPER(email)=UPPER(?) and status = 'ACTIVE'
jdbcRealm.userRolesQuery = SELECT r.unique_name FROM permission_role_employee pe JOIN permission_role r ON pe.permission_role_fk = r.permission_role_id JOIN employee e ON pe.employee_fk = e.employee_id JOIN user u ON e.user_fk = u.user_id WHERE UPPER(u.email)=UPPER(?) AND pe.delete_flag = false
jdbcRealm.permissionsQuery = SELECT p.unique_name FROM permission_role_object po JOIN permission p ON po.permission_fk = p.permission_id JOIN permission_role r ON po.permission_role_fk = r.permission_role_id WHERE UPPER(r.unique_name)=UPPER(?) AND po.delete_flag = false
jdbcRealm.dataSource = $ds
jdbcRealm.credentialsMatcher = $sha512Matcher
# Realm for Token Login
tcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
tcRealm.permissionsLookupEnabled = true
tcRealm.authenticationQuery = SELECT token FROM api_token WHERE token = ?
tcRealm.userRolesQuery = SELECT r.unique_name FROM permission_role_employee pe JOIN permission_role r ON pe.permission_role_fk = r.permission_role_id JOIN employee e ON pe.employee_fk = e.employee_id JOIN api_token t ON t.employee_fk = e.employee_id WHERE UPPER(t.token)=UPPER(?) AND t.delete_flag = false
tcRealm.permissionsQuery = SELECT p.unique_name FROM permission_role_object po JOIN permission p ON po.permission_fk = p.permission_id JOIN permission_role r ON po.permission_role_fk = r.permission_role_id WHERE UPPER(r.unique_name)=UPPER(?) AND po.delete_flag = false
tcRealm.dataSource = $ds
# AuthStrategy
authenticator = org.apache.shiro.authc.pam.ModularRealmAuthenticator
authcStrategy = org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy
authenticator = org.apache.shiro.authc.pam.ModularRealmAuthenticator
securityManager.authenticator = $authenticator
securityManager.authenticator.authenticationStrategy = $authcStrategy
securityManager.realms = $jdbcRealm, $tcRealm, $pac4jRealm
# Caching
cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
securityManager.cacheManager = $cacheManager
# Using default form based security filter org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authc = org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authc.loginUrl = /common/login.jsf
authc.successUrl = /portal/dashboard.jsf
# Redirect to an access denied page if user does not have access rights
#[roles]
#roles.unauthorizedUrl = /common/access-denied.jsf
#perms.unauthorizedUrl = /accessdenied.jsp
anyofpermission = com.myapp.util.CustomPermissionsAuthorizationFilter
# Protected URLs
[urls]
/service = noSessionCreation, anon
## OTHER
/WEB-INF/layout/portal/** = authc
/portal/** = authc
/admin/** = authc
/community/** = authc
The Shiro
JdbcRealmis anAuthorizingRealmwith JDBC capabilities.The
pac4jRealmis also anAuthorizingRealmwith pac4j logic, there is no JDBC capability in thepac4jRealm.Thus you cannot configure things only in the
shiro.inifile.You should certainly create a pac4j
AuthorizationGeneratorwhich retrieves the roles and permissions from the database and set it to theOidcClient.