您的位置:首页 > 其它

Shiro入门学习四

2017-11-02 15:19 351 查看

Shiro入门学习四

授权

授权流程

授权流程参考官网Authorization Sequence,也可参阅第三章 授权——《跟我学Shiro》



流程如下:

首先调用
Subject.isPermitted*/hasRole*
接口,其会委托给SecurityManager,而SecurityManager接着会委托给Authorizer;

Authorizer是真正的授权者,如果我们调用如
isPermitted(“user:view”)
,其首先会通过PermissionResolver把字符串转换成相应的Permission实例;

在进行授权之前,其会调用相应的Realm获取Subject相应的角色/权限用于匹配传入的角色/权限;

Authorizer会判断Realm的角色/权限是否和传入的匹配,如果有多个Realm,会委托给ModularRealmAuthorizer进行循环判断,如果匹配如
isPermitted*/hasRole*
会返回true,否则返回false表示授权失败。

在授权中需了解的几个关键对象:

主提(subject):即访问应用的用户,在Shiro中使用Subject代表该用户

资源(resources):在应用中用户可以访问的任何东西

权限:对某个资源的细粒度的CRUD

角色:角色代表了操作集合,可以理解为权限的集合

JavaSE例子

角色

shiro.ini
文件中,添加如下的内容,配置用户拥有的角色:

[users]
kh=123,r1,r2
zhangsan=111,r3
lisi=123,r2,r3


测试如下:

public Subject login(String username, String password) {
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);

Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);
return subject;
} catch (UnknownAccountException e) {
System.out.println("用户不存在");
} catch (IncorrectCredentialsException e) {
System.out.println("密码不存在");
} catch (AuthenticationException e) {
System.out.println("认证异常");
}
return null;
}

@Test
public void testRole() {
Subject subject = login("kh", "123");
System.out.println(subject.hasRole("r1"));
System.out.println(subject.hasAllRoles(Arrays.asList("r1","r2","r3")));
System.out.println(subject.hasRoles(Arrays.asList("r1","r2","r3"))[2]);
subject.checkRole("r1");
}


做一些说明:

1.
hasRole("r1")
是否有
r1
角色,返回值为boolean

2.
hasAllRoles
是否有所有的权限,返回值为boolean

3.
hasRoles
返回值为boolean为数组

4.
checkRole
方法没有返回值,如果没有对应的角色,则抛异常

权限

如下配置权限:

[roles]
r1=user:create,user:delete
r2=topic:*


r1=user:create,user:delete
表示r1具有user的create,delete权限,可简写为
r1="user:create,delete"
(注意带有引号)

r2=topic:*
表示r2具有topic的所有权限

测试如下:

@Test
public void testPermission() {
Subject subject = login("kh", "123");
// 是否具有user的view权限 false
System.out.println(subject.isPermitted("user:view"));
// 是否具有user的delete权限 true
System.out.println(subject.isPermitted("user:delete"));
// 是否具有topic的create权限 true
System.out.println(subject.isPermitted("topic:create"));
}


如下的
r1
:

r1="user:create,delete","dep:del,view",classroom


classroom
等同于
classroom:*


r3=*:view
表示r3具有任何的view的权限,如
test:view
,但
test:abc:view
则不行

自定义realm中权限的处理

可参考在Spring MVC中使用Apache Shiro安全框架

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//获取登录时输入的用户名
String loginName = (String) principalCollection.fromRealm(getName()).iterator().next();
//到数据库查是否有此对象
User user = this.getDao().findByName(loginName);
if (user != null) {
//权限信息对象info,用来存放查出的用户的所有的角色(role)及权限(permission)
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//用户的角色集合
info.setRoles(user.getRolesName());
//用户的角色对应的所有权限,如果只使用角色定义访问权限,下面的四行可以不要
List<Role> roleList = user.getRoleList();
for (Role role : roleList) {
info.addStringPermissions(role.getPermissionsString());
}
return info;
}
return null;
}


授权推荐教程

SpringBoot+shiro整合学习之登录认证和权限控制

加密

参阅第五章 编码/加密——《跟我学Shiro》

散列算法一般用于生成数据的摘要信息,是一种不可逆的算法,一般适合存储密码之类的数据,常见的散列算法如MD5、SHA等

//202cb962ac59075b964b07152d234b70
System.out.println(new Md5Hash("123").toHex());
//ICy5YqxZB1uWSwcVLSNLcA==
System.out.println(new Md5Hash("123").toBase64());


一般进行散列时最好提供一个salt(盐),比如加密密码“admin”,产生的散列值是“21232f297a57a5a743894a0e4a801fc3”,可以到一些md5解密网站很容易的通过散列值得到密码“admin”,即如果直接对密码进行散列相对来说破解更容易,此时我们可以加一些只有系统知道的干扰数据,如用户名和ID(即盐);这样散列的对象是“密码+用户名+ID”,这样生成的散列值相对来说更难破解。

String str = "hello";
String salt = "123";
String md5 = new Md5Hash(str, salt).toString();//还可以转换为 toBase64()/toHex()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  shiro