token携带身份和凭证信息--->subject发起认证--->SimpleAccountRealm(doGetAuthenticationInfo)获取配置文件中的用户信息---->CredentialsMatcher接口的实现类SimpleCredentialsMatcher:doCredentialsMatch方法对配置文件中的信息与token携带的信息进行比对--->认证成功或者失败。
以下代码或者截图贴出最重要的地方.
类继承关系
AuthenticatingRealm类
abstract class AuthenticatingRealm{ //凭证匹配器 接口,其实现类做数据比对 private CredentialsMatcher credentialsMatcher; //获取配置文件中的用户信息 protected abstract AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken var1) throws AuthenticationException; }该抽象方法返回类型AuthenticationInfo接口:
AuthorizingRealm类 抽象方法后面测试授权时使用
abstract class AuthorizingRealm{ // //该抽象方法 获取数据 获取授权的数据 protected abstract AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection var1); }该抽象方法返回类型AuthorizationInfo接口:
CredentialsMatcher凭证匹配器接口:
其中:SimpleCredentialsMatcher是shiro中默认的凭证匹配器,其子类Hashxxx等都是做加密认证时使用
注意:需要导入一个jar
<dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency>坑:Caused by: java.lang.IllegalStateException: Required 'hashAlgorithmName' property has not been set. This is required to execute the hashing algorithm.
HashedCredentialsMatcher类中set方法非常规,set方法为:setHashAlgorithmName
AuthenticationInfo doGetAuthenticationInfo()来自于AuthenticatingRealm类,获取认证数据
AuthorizationInfo doGetAuthorizationInfo()来自于AuthorizingRealm类,获取授权数据
public class MyRealm extends AuthorizingRealm { @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { String principal =(String) authenticationToken.getPrincipal(); //userDao.queryUserByUserName SqlSession sqlSession = null; try { sqlSession = MySqlSession.getSqlSession(); } catch (IOException e) { e.printStackTrace(); } UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.queryUserByUserName(principal); /* * ByteSource.Util.bytes("salt") 盐字段来自数据库,凭证匹配器不能写死盐值 * 安全管理器可以获取到AuthenticationInfo中的盐值 对用户界面的凭证加密 * */ AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(principal,user.getPassword(),ByteSource.Util.bytes("salt"),this.getName()); return authenticationInfo; } @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { //获取身份信息 Principal用户名、手机号、邮箱地址等 一个主体可以有多个身份,但是必须有一个主身份(Primary Principal) String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal(); /* * 用户----角色----权限 * 中间表 中间表 * */ //由primaryPrincipal查库--->获得角色info ---->获取权限info SqlSession sqlSession = null; try { sqlSession = MySqlSession.getSqlSession(); } catch (IOException e) { e.printStackTrace(); } UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.queryUserByUserName(primaryPrincipal); //测试基于角色的授权 /*if (primaryPrincipal.equals(user.getUsername())){ // class SimpleAuthorizationInfo implements AuthorizationInfo SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); authorizationInfo.addRole("super"); return authorizationInfo; }*/ //测试基于资源的授权 if(primaryPrincipal.equals(user.getUsername())){ SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); authorizationInfo.addStringPermission("user:delete"); authorizationInfo.addStringPermissions(Arrays.asList("admin:delete","admin:add")); return authorizationInfo; } return null; } }基于角色
//判断当前主体是否包含此角色 boolean b = subject.hasRole("super"); List<String> list = Arrays.asList("super", "admin"); //判断当前主体是否包含某个角色 boolean[] booleans = subject.hasRoles(list); //判断当前主体是否包含全部的角色 boolean b = subject.hasAllRoles(list);基于资源
boolean b = subject.isPermitted("admin:delete"); String[] strs={"admin:delete", "admin:add"}; boolean[] permitted = subject.isPermitted(strs); boolean permittedAll = subject.isPermittedAll(strs);权限字符串的规则是:“资源标识符:操作:资源实例标识符”,意思是对哪个资源的哪个实例具有什么操作,“:”是资源/操作/实例的分割符,权限字符串也可以使用*通配符。
例子:
用户创建权限:user:create,或user:create:*用户修改实例001的权限:user:update:001用户实例001的所有权限:user:*:001转载于:https://www.cnblogs.com/mzc1997/p/10223014.html