I’m using Tapestry-Security which uses Apache Shiro
I have a custom realm which handles authorization and authentication. Our authentication technically happens using a remote service, which returns a username and a set of roles. I just pass the username into my custom AuthenticationToken which allows me to query our local db and set the SimpleAuthenticationInfo.
I can’t figure out how to populate the AuthorizationInfo doGetAuthorizationInfo method using the list of roles returned to me from our remote service. Below is the code I’m using to populate the realm.
Login.class
//Remote authentication service
RemoteLoginClient client = new RemoteLoginClient();
RemoteSubject authenticate = client.authenticate(username, password);
//tapestry security authentication
Subject currentUser = SecurityUtils.getSubject();
CustomAuthenticationToken token = new
CustomAuthenticationToken(authenticate.getUsername());
System.out.println("roles" + authenticate.getRoles());
currentUser.login(token);
AuthorizationInfo method inside customRealm
public class CustomRealm extends AuthorizingRealm {
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
CustomAuthenticationToken upToken = (CustomAuthenticationToken ) token;
String email = upToken.getUsername();
ApplicationUser applicationUser = (ApplicationUser) session.createCriteria(ApplicationUser.class)
.add(Restrictions.like("email", email + "%"))
.uniqueResult();
if (applicationUser == null) {
throw new UnknownAccountException("User doesn't exist in EPRS database");
}
return buildAuthenticationInfo(applicationUser.getId());
}
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//Not sure how to populate the principle or
//read the principle to populate the SimpleAuthorizationInfo
return new SimpleAuthorizationInfo(roleNames);
}
Extending
AuthorizingRealmis a good place to start if you need both authentication and authorization. Also, as PepperBob has already said, while you’re at it, theAccountinterface and itsSimpleAccountimplementation support both authentication and authorization in a single interface, so you don’t need much separate code fordoGetAuthenticationInfo()anddoGetAuthorizationInfo()and can just return the same object from both methods.To get the authorization information, you need to do two things:
getAvailablePrincipal()method (neatly predefined inAuthorizingRealm).setRoles()on your account object.…and you’re done.
Edited to add:
This would be a very simple way to store the roles until you need them. Note that the actual authentication is done in the realm, which has a dependency on
RemoteLoginClient.