【问题标题】:How do concepts of User (UserAccount) and Realm relate in Apache Shiro?Apache Shiro 中的用户(UserAccount)和领域的概念如何关联?
【发布时间】:2013-10-08 02:03:07
【问题描述】:

我正在阅读Apache Shiro 并想看看我是否正确地理解了这个心理模型。

来自docs:“Realm 是一个组件,可以访问特定于应用程序的安全数据,例如usersrolespermissions”。 .. “领域通常与数据源(例如关系数据库、LDAP 目录、文件系统或其他类似资源)具有一对一的关联。”

此外,我了解到application 可能包含多个realms 用于身份验证和授权。

很好,但是Realms 与用户的概念有什么关系?

  • 是否每个Realm 都应该是用户空间的一个分区?即:User 可能只出现在 1 个Realm
  • 或者,这就是我所期待的,Realms 可用于将身份验证和授权分层叠加,可以在同一个 User 上工作。但是,在这种情况下,User 在哪里管理?我猜它应该在Realm 之外的某个地方,但是在哪里?

也许我对此感到困惑,因为我认为User 是一个单一的实体(例如:我只能有一个)。而是应该将User 视为UserAccount。即:每个Realm 管理它自己的Useraccounts(在称为User 的文档中),但User 可能有多个UserAcounts。那是对的吗?

假设以上是正确的:

  • 是否有任何逻辑可以让我查询给定用户的所有UserAccounts?即:基本上将所有Useraccounts 合并在一起以获得User 的完整视图?
  • 在这种情况下User 的概念(1 个User 可能有多个UserAccounts)甚至存在于Shiro 中吗?

【问题讨论】:

    标签: java shiro


    【解决方案1】:

    您在authenticationStrategy 中定义Realms 之间的关系。让我们看看这个例子。只有当他通过所有领域的认证时,用户才会被认证。您可以制作自己的 authenticationStrategy 实现,它说只需一次成功的身份验证就足够了。

    在示例中,我们结合 JDBC 领域来存储用户名(无密码)并针对 LDAP 对其进行身份验证。

    假设您将添加另一个 LDAP 领域并创建 authenticationStrategy,其中并非需要针对领域的所有身份验证。但只需对 LDAP 进行一次成功的身份验证就足够了。

    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
    

    【讨论】:

    • 这个例子不应该使用FirstSuccessfulStrategy而不是AllSuccessfulStrategy吗?
    • 其目的是仅授予项目数据库中的用户访问权限,并重用公司范围的 LDAP 身份验证。所以,这就是 jdbcRealm 有 noPassWordCredentialMatcher 的原因。
    • 啊,我想我明白了。因此,无密码匹配器只检查数据库中是否存在用户 ID 并返回适当的结果。有道理。
    • 您也可以使用标准的org.apache.shiro.authc.credential.AllowAllCredentialsMatcher 作为凭证​​匹配器。它允许所有凭据,但至少需要一个用户名,这意味着身份验证查询应该返回一个值。如果不匹配,则不会匹配,因此在此配置中,只有在 auth 表中找到名称时才会通过。
    猜你喜欢
    • 2013-06-19
    • 2016-08-13
    • 2018-03-14
    • 2012-11-06
    • 2015-05-31
    • 1970-01-01
    • 2011-06-18
    • 2016-01-17
    • 1970-01-01
    相关资源
    最近更新 更多