5

I'm reading up on Apache Shiro and like to see if I got this mental model right.

From the docs: "A Realm is a component that can access application-specific security data such as users, roles, and permissions". .. "Realms usually have a 1-to-1 correlation with a data source such as a relational database, LDAP directory, file system, or other similar resource. "

Moreover, I've read that an application may include multiple realms for its authentication and authorization purposes.

Ok so great, but how do this Realms relate to the concept of a User?

  • is every Realm expected to be a partition over the user-space? I.e: a User may only ever occur in 1 Realm
  • or, and this is what I'm expecting, Realms can be used to layer authentication & authorization on top of eachother and may work on the same User. However in that case, where is the User managed? It should be somewhere external to a Realm I guess, but where?

Perhaps I'm confused by this because I'm thinking of User as a single entity (e.g: of me there can be only one) . And should instead be thinking of User as a UserAccount. I.e.: Each Realm manages it's own Useraccounts (in the docs called User), but a User may have multiple UserAcounts. Is that correct?

Assuming the above is correct:

  • is there any logic that enables me to query for all UserAccounts of a given User? I.e: basically merging all Useraccounts together to get a complete view of the User?
  • does the concept of User in this case (1 User possibly having multiple UserAccounts) even exist in Shiro?
JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
Geert-Jan
  • 18,623
  • 16
  • 75
  • 137

1 Answers1

4

You define relation between Realms in authenticationStrategy. Lets see the example. User will be authenticated only when he passes authentication against all realms. You can make your own authenticationStrategy implementation which says just one successful authentication is enough or whatsoever.

In the example, we combine JDBC realm to store users names (no passwords) and authenticate it against LDAP.

Lets say you will add one another LDAP realm and create authenticationStrategy, where not all authentications against realm are needed. But just one successful authentication against LDAP is enough.

shiro.ini

ds = org.apache.shiro.jndi.JndiObjectFactory
ds.requiredType = javax.sql.DataSource
ds.resourceName = java:comp/env/jdbc/xxx

noPassWordCredentialMatcher = eu.corp.domain.auth.NoPassMatcher

ldapRealm = eu.corp.domain.auth.CustomActiveDirectoryRealm
ldapRealm.searchBase = OU=USERS,OU=EN,DC=our,DC=corp
ldapRealm.url = ldap://our.corp:389
ldapRealm.principalSuffix = @our.corp

jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.permissionsLookupEnabled = true
jdbcRealm.dataSource = $ds
jdbcRealm.credentialsMatcher = $noPassWordCredentialMatcher

jdbcRealm.authenticationQuery = SELECT name FROM auth WHERE name = ?
jdbcRealm.userRolesQuery = SELECT role.shortcut FROM auth LEFT JOIN auth_role ON auth_role.auth_id = auth.id LEFT JOIN role ON role.id = auth_role.role_id WHERE auth.name = ?
jdbcRealm.permissionsQuery = SELECT permission.shortcut FROM role JOIN role_permission ON role_permission.role_id = role.id JOIN permission ON permission.id = role_permission.permission_id WHERE role.shortcut = ?

cacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
securityManager.cacheManager = $cacheManager

securityManager.realms = $ldapRealm, $jdbcRealm
authcStrategy = org.apache.shiro.authc.pam.AllSuccessfulStrategy
securityManager.authenticator.authenticationStrategy = $authcStrategy
Jens Piegsa
  • 7,399
  • 5
  • 58
  • 106
Milan Baran
  • 4,133
  • 2
  • 32
  • 49
  • Shouldn't this example use the FirstSuccessfulStrategy instead of the AllSuccessfulStrategy? – bspkrs Feb 09 '16 at 00:33
  • 1
    The intention was to grant access only to users in project DB and also reuse company wide LDAP authentification. So, thats why jdbcRealm have noPassWordCredentialMatcher. – Milan Baran Feb 12 '16 at 11:40
  • Ah, I think I get it. So the no password matcher just checks that the user ID exists in the DB and returns the appropriate result. Makes sense. – bspkrs Feb 15 '16 at 17:22
  • You could use the standard `org.apache.shiro.authc.credential.AllowAllCredentialsMatcher` as the credential matcher as well. It allows all credentials but expects at least a username so that means the authentication query should return a value. If it doesn't it won't match, so in this config it will only pass if the name is found in the auth table. – Roberg Aug 21 '17 at 19:10