realm有授权和认证两部分,其中认证在先,授权在后
package cn.taotao.dao; import org.apache.catalina.realm.AuthenticatedUserRealm; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthenticatingRealm; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; //public class UserRealm extends AuthenticatingRealm { public class UserRealm extends AuthorizingRealm { @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { Object principal=authenticationToken.getPrincipal(); // 这一步是需要去数据库取出密码的 // Object credentials=new String("123456"); // 若配置了加密,在realm中配置了密码匹配器,这里需要的是数据库的加密后的密码 Object credentials=new String("e10adc3949ba59abbe56e057f20f883e"); String realmName=this.getClass().getSimpleName(); // 这里的密码,是去数据库中取,根据token传来的用户名,去数据库中取。 SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal,credentials,realmName); return info; } @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.addRole("role1"); info.addStringPermission("*:*"); return info; } }
因为这里的授权,每次都会查数据库,可能导致数据库频繁,但是认证只查询一次。
可以把授权里的,查询那一步,加入到认证里,只是查询到了结果集,
List<Roles> roles = this.RoleService.getRolesByName("xxx")
然后构造一个ActiveUser,在ActivieUser构造方法中把Roles和perimisstion传进去,然后再在
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(ActiveUser,credentials,realmName);
这一步把activeuser传进去
测试类代码
@Test void testRealm(){ String username="zhangsan"; String password = "123456"; // 模拟用户键盘输入 // 创建工厂,注意引入的包名,SecurityManager 是shiro的包 Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); // Factory<SecurityManager> factory = new SecurityManagerFactory // 取得安全管理器实例 DefaultSecurityManager securityManager = (DefaultSecurityManager) factory.getInstance(); UserRealm userRealm= new UserRealm(); HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher("MD5"); userRealm.setCredentialsMatcher(credentialsMatcher); securityManager.setRealm(userRealm); SecurityUtils.setSecurityManager(securityManager); Subject subject = SecurityUtils.getSubject(); AuthenticationToken authenticationToken = new UsernamePasswordToken(username,password); subject.login(authenticationToken); System.out.println("认证是否realm,:"+subject.isAuthenticated()); //subject boolean hasRole = subject.hasRole("role1"); //System.out.println("看是否用ini文件的角色role吗?:"+hasRole); //需要在realm中取得info后,自增加role System.out.println("看是否用reale文件的角色role吗?:"+hasRole); // 支持通配符的权限。 info.addStringPermission("*:*"); boolean permitted = subject.isPermitted("user:queryxxx"); System.out.println("是否有permitted:"+permitted); }