编写自定义 Shiro 领域

Posted

技术标签:

【中文标题】编写自定义 Shiro 领域【英文标题】:Writing custom Shiro realm 【发布时间】:2015-01-19 17:32:43 【问题描述】:

我正在构建自己的 AuthorizingRealm 子类,并且很难将其连接到我的 SecurityManager

我的境界的本质:

public class MyRealm extends AuthorizingRealm  
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException  
        try  
            // My custom logic here 

         catch(Throwable t)  
            System.out.println(t.getMessage()); 
         
        SimpleAuthenticationInfo authn = new SimpleAuthenticationInfo(new MyUser(), "somePassword");
        return authn;
     

    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals)  
        try  
            // My custom logic here 
         catch(Throwable t)  
            System.out.println(t.getMessage()); 
        
        return new SimpleAuthorizationInfo();
     

然后在我的“shiro.ini”中:

# ======================= 
# Shiro INI configuration 
# ======================= 
[main] 
myRealm = com.me.myapp.security.MyRealm 

然后在我的 Driver 类/main 方法(我用于测试)中:

public class Driver  
    public static void main(String[] args)  
        Driver d = new Driver(); 
        d.test(); 
     

    public void test()  
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); 
        SecurityManager securityManager = factory.getInstance(); 
        SecurityUtils.setSecurityManager(securityManager); 

        UsernamePasswordToken token = new UsernamePasswordToken("", ""); 
        token.setRememberMe(true); 

        System.out.println("Shiro props:"); 
        System.out.println(securityManager.getProperties()); 

        Subject currentUser = SecurityUtils.getSubject() 

        try  
            currentUser.login(token) 

            println "I think this worked!" 
         catch (UnknownAccountException uae)  
            println "Exception: $uae" 
         catch (IncorrectCredentialsException ice)  
            println "Exception: $ice" 
         catch (LockedAccountException lae)  
            println "Exception: $lae" 
         catch (ExcessiveAttemptsException eae)  
            println "Exception: $eae" 
         catch (AuthenticationException ae)  
            println "Exception: $ae" 
         
     
 

当我运行它时,我得到:

Shiro props: 
[class:class org.apache.shiro.mgt.DefaultSecurityManager, cacheManager:null, subjectFactory:org.apache.shiro.mgt.DefaultSubjectFactory@6a2b8b42, authorizer:org.apache.shiro.authz.ModularRealmAuthorizer@50c3d082, realms:[com.me.myapp.security.MyRealm@67ae303a], subjectDAO:org.apache.shiro.mgt.DefaultSubjectDAO@5ce06503, rememberMeManager:null, authenticator:org.apache.shiro.authc.pam.ModularRealmAuthenticator@1007d798, sessionManager:org.apache.shiro.session.mgt.DefaultSessionManager@72db4460] 
Exception: org.apache.shiro.authc.AuthenticationException: Authentication failed for token submission [org.apache.shiro.authc.UsernamePasswordToken - , rememberMe=true].  Possible unexpected error? (Typical or expected login exceptions should extend from AuthenticationException). 

所以它看起来像是在读取我的 shiro.ini,因为它选择了正确的领域,但 MyRealm 不做任何事情,除了存根不管提供的用户名/密码如何都应该进行身份验证的虚拟用户。关于我要去哪里出错的任何想法?

【问题讨论】:

【参考方案1】:

您似乎已经正确地创建了一个领域,但没有告诉SecurityManager 它是要使用的领域之一。这样,它只是在shiro.inimain 部分中创建的另一个对象。

要告诉 Shiro 的 SecurityManager 它需要使用 myRealm 作为 Realm,您需要将其添加到您的 shiro.ini

securityManager.realms = $myRealm 

【讨论】:

【参考方案2】:

我自己没有这样做,但是您可以尝试以下几件事:

    如果您不需要授权逻辑,请考虑子类化 AuthenticatingRealm 而不是 AuthorizingRealm

    在方法 doGetAuthenticationInfo 中,考虑使用以下代码:

    SimpleAuthenticationInfo authn = new SimpleAuthenticationInfo(token.getPrincipal(), token.getCredentials(), "myRealm");

【讨论】:

【参考方案3】:

将此添加到您的 shiro.ini:securityManager.realms = $myRealm 然后在您的驱动程序类中

UsernamePasswordToken token = new UsernamePasswordToken("", "somePassword"); 

而不是空密码。

我认为这行得通!

【讨论】:

感谢@Luca Rasconi,但是您的建议并没有改变任何东西(与我上面描述的行为相同)。还有其他想法/想法吗?再次感谢!

以上是关于编写自定义 Shiro 领域的主要内容,如果未能解决你的问题,请参考以下文章

将 Shiro 的 PasswordMatcher 与自定义领域一起使用

对 Apache Shiro 和自定义授权领域感到困惑

Apache Shiro - 自定义 jdbc 领域 - 读取角色/权限

Apache Shiro 身份验证自定义

需要重写或实现哪些类或方法才能仅自定义 Shiro 的身份验证逻辑?

解决自定义Shiro.Realm扩展类不能用注解(@Resource或@Autowire)自动装配的问题