概念
授权,又称作为访问控制,是对资源的访问管理的过程,即对于认证通过的用户,授予他可以访问某些资源的权限。
授权的方式
shiro支持三种方式的授权:
代码触发
通过写if/else 授权代码块完成
Subject subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {
//有权限
} else {
//无权限
}
注解触发
通过在执行的Java方法上放置相应的注解完成
@RequiresRoles("admin")
public void hello() {
//有权限
}
标签触发
在JSP/GSP页面通过相应的标签完成
<shiro:hasRole name="admin">
<!— 有权限—>
</shiro:hasRole>
注意本文先讲代码触发,后面两种情况再后面案例中使用讲解。
授权流程图
简单授权实现
在ini.xml文件中设置
[users]
#用户zhang的密码是123,此用户具有role1和role2两个角色
zhang=123,role1,role2
wang=123,role2
[roles]
#角色role1对资源user拥有create、update权限
role1=user:create,user:update
#角色role2对资源user拥有create、delete权限
role2=user:create,user:delete
#角色role3对资源user拥有create权限
role3=user:create
验证角色和权限
@Test
public void test() {
// 1.获取SecurityManager工厂对象
Factory<SecurityManager> factory =
new IniSecurityManagerFactory("classpath:shiro.ini");
// 2.通过Factory对象获取SecurityManager对象
SecurityManager securityManager = factory.getInstance();
// 3.将SecurityManager对象添加到当前运行环境中
SecurityUtils.setSecurityManager(securityManager);
// 4.获取Subject对象
Subject subject = SecurityUtils.getSubject();
AuthenticationToken token = new UsernamePasswordToken("zhang", "123");
// 登录操作
try {
subject.login(token);
} catch (UnknownAccountException e) {
System.out.println("账号出错...");
} catch(IncorrectCredentialsException e){
System.out.println("密码出错...");
}
// 获取登录的状态
System.out.println(subject.isAuthenticated());
// 认证通过后进行权限验证 角色
System.out.println(subject.getPrincipal()+"是否具有role1角色:"+subject.hasRole("role1"));
System.out.println(subject.getPrincipal()+"是否具有role3角色:"+subject.hasRole("role3"));
boolean[] types = subject.hasRoles(Arrays.asList("role1","role2"));
System.out.println(subject.getPrincipal()+"是否具有role1和role2角色:"+types[0]+","+types[1]);
//subject.checkRole("role1");
//subject.checkRole("role3");
// 验证权限
System.out.println(subject.getPrincipal()+"是否具有user:create权限:"+subject.isPermitted("user:create"));
System.out.println(subject.getPrincipal()+"是否具有user:delete角色:"+subject.isPermitted("user:delete"));
boolean t = subject.isPermittedAll("user:create","user:delete");
System.out.println(subject.getPrincipal()+"是否具有user:create和user:delete的权限:"+t);
}
输出结果:
true
zhang是否具有role1角色:true
zhang是否具有role3角色:false
zhang是否具有role1和role2角色:true,true
zhang是否具有user:create权限:true
zhang是否具有user:delete角色:true
zhang是否具有user:create和user:delete的权限:true
注意
subject.checkRole("role3");
subject.checkPermission("aaa");
检查是否存在该角色和权限,如果不存在则会抛异常
自定义领域授权
重写授权的方法
/**
* 授权方法
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 获取当前登录的账号
String userName = (String) principals.getPrimaryPrincipal();
// 根据账号信息 可以去数据库中查询出该账号对应的 角色和权限信息
List<String> roles = new ArrayList<>();
roles.add("r1");
roles.add("r2");
roles.add("r3");
List<String> ps = new ArrayList<>();
ps.add("order:create");
ps.add("order:query");
ps.add("order:delete");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 添加角色
info.addRole("role1");
info.addRoles(roles);
// 添加权限
info.addStringPermission("user:update");
info.addStringPermissions(ps);
return info;
}
ini.xml文件
[main]
#自定义 realm
customRealm=com.dpb.realm.MyRealm
#将realm设置到securityManager
securityManager.realms=$customRealm
测试方法和之前一样
@Test
public void test() {
// 1.获取SecurityManager工厂对象
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
// 2.通过Factory对象获取SecurityManager对象
SecurityManager securityManager = factory.getInstance();
// 3.将SecurityManager对象添加到当前运行环境中
SecurityUtils.setSecurityManager(securityManager);
// 4.获取Subject对象
Subject subject = SecurityUtils.getSubject();
AuthenticationToken token = new UsernamePasswordToken("root", "123456");
// 登录操作
try {
subject.login(token);
} catch (UnknownAccountException e) {
System.out.println("账号出错...");
} catch (IncorrectCredentialsException e) {
System.out.println("密码出错...");
}
// 获取登录的状态
System.out.println(subject.isAuthenticated());
// 获取登录的状态
System.out.println(subject.isAuthenticated());
// 认证通过后进行权限验证 角色
System.out.println(subject.getPrincipal() + "是否具有role1角色:" + subject.hasRole("role1"));
System.out.println(subject.getPrincipal() + "是否具有role3角色:" + subject.hasRole("role3"));
boolean[] types = subject.hasRoles(Arrays.asList("role1", "role2"));
System.out.println(subject.getPrincipal() + "是否具有role1和role2角色:" + types[0] + "," + types[1]);
// subject.checkRole("role1");
//subject.checkRole("role3");
// 验证权限
System.out.println(subject.getPrincipal() + "是否具有user:create权限:" + subject.isPermitted("user:create"));
System.out.println(subject.getPrincipal() + "是否具有user:delete角色:" + subject.isPermitted("user:delete"));
boolean t = subject.isPermittedAll("user:create", "user:delete");
System.out.println(subject.getPrincipal() + "是否具有user:create和user:delete的权限:" + t);
//subject.checkPermission("aaa");
}
Java帮帮
非盈利学习社区
官网:www.javahelp.com.cn
职涯宝
时间宝贵,阅读价值
官网:www.zhiya360.com
九点编程
深夜学习,未来可期
悟空教程
强大自己,立于不败
Python帮帮
人工智能,不得不看