Writing custom Shiro realm

I am constructing my own AuthorizingRealm subclass, and am having a tough time wiring it up to my SecurityManager .

The essence of my realm:

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();
    } 
}

Then in my 'shiro.ini':

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

Then in my Driver class/main method (that I'm using for testing):

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}" 
        } 
    } 
} 

When I run this I get:

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). 

So it looks like its reading my shiro.ini because its picking up the correct realm, but MyRealm doesn't do anything except stub out dummy users that should authenticated regardless of the username/password supplied. Any ideas as to where I'm going awry?


You can take a look at the source code of the Stormpath Shiro Plugin in github: Plugin here and Sample App using the Plugin here.

We have implemented our one AuthorizingRealm (similar to what you need). You may be interested in taking a look at:

  • https://github.com/stormpath/stormpath-shiro/blob/master/core/src/main/java/com/stormpath/shiro/realm/ApplicationRealm.java
  • https://github.com/stormpath/stormpath-shiro-web-sample/blob/master/src/main/webapp/WEB-INF/shiro.ini
  • BTW, in your shiro.ini you need to add this: securityManager.realm = $myRealm


    add this to your shiro.ini: securityManager.realms = $myRealm
    then in your Driver class

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

    instead of an empty passowrd.

    I think this worked!


    I have not done this myself, but here are a couple of things you can try:

  • If you don't need authorization logic, consider subclassing AuthenticatingRealm instead of AuthorizingRealm

  • In method doGetAuthenticationInfo, consider using this code:

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

  • 链接地址: http://www.djcxy.com/p/23570.html

    上一篇: Aviary在Android L上崩溃(5.0)

    下一篇: 编写自定义Shiro领域