写自定义Shiro境界

时间:2014-11-21 14:27:53

标签: security authentication authorization shiro

我正在构建自己的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除了存根应该进行身份验证的虚拟用户之外不会做任何事情,无论提供的用户名/密码如何。关于我哪里出错的任何想法?

4 个答案:

答案 0 :(得分:3)

您可以使用插件here查看github中的Stormpath Shiro插件的源代码:插件here和示例应用程序。

我们实施了一个AuthorizingRealm(类似于您需要的)。您可能有兴趣看看:

  1. https://github.com/stormpath/stormpath-shiro/blob/master/core/src/main/java/com/stormpath/shiro/realm/ApplicationRealm.java
  2. https://github.com/stormpath/stormpath-shiro-web-sample/blob/master/src/main/webapp/WEB-INF/shiro.ini
  3. 顺便说一句,在您的shiro.ini中,您需要添加以下内容:securityManager.realm = $myRealm

答案 1 :(得分:0)

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

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

而不是空的passowrd。

我认为这有效!

答案 2 :(得分:0)

我自己没有这样做,但这里有几件你可以尝试的事情:

  1. 如果您不需要授权逻辑,请考虑继承AuthenticatingRealm而不是AuthorizingRealm

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

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

答案 3 :(得分:0)

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

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

shiro.ini