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:
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");
下一篇: 编写自定义Shiro领域