shiro 授权
一, shiro授权方式3种
- 编程式
- 注解式
- jsp式
- 授权操作使用注解式更好
二,授权的具体操作- 进行授权,前提是用户必须已经经过认证
- 角色是一组权限的集合
1,配置shiro文件
#配置用户名和密码
[users]
zhangsan=123456,role1
lisi=123456,role2,role3
wangwu=123456,role4
#配置角色
[roles]
role1=user:query,user:add,user:update,user:delete,user:exprot
role2=user:query
role3=user:query,user:add,user:update,user:delete
role4=user:query,user:add,user:update
2,验证用户主体是否有权限和角色
public static void main(String []args){
//1.创建用户数据
String username = "zhangsan";
String password = "123456";
// 2.创建factory工厂,从ini文件拿数据
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//3.使用factory创建SecurityManager (有shiro信息)
DefaultSecurityManager securityManager = (DefaultSecurityManager) factory.getInstance();
//4.将UserRealm注入到完全管理器
securityManager.setRealm(new UserRealm2());
//5.把当前安全管理器注入到线程中
SecurityUtils.setSecurityManager(securityManager);
//6.获得主体用户
Subject subject = SecurityUtils.getSubject();
//7.将用户名和密码封装到token
UsernamePasswordToken token = new UsernamePasswordToken(username,password);
//8.进行登录
try {
subject.login(token);//进行认证,如果失败会抛异常
System.out.println("登陆成功");
}catch (IncorrectCredentialsException e){
System.out.println("密码不正确");
}catch (UnknownAccountException e){
System.out.println("用户名不存在");
}catch (AuthenticationException e){
System.out.println("用户名或密码正确");
}
if(subject.isAuthenticated()){
boolean hasRole = subject.hasRole("超级管理员");
System.out.println(username+"是否有超级管理员的角色:"+hasRole);//false
boolean hasRole2 = subject.hasRole("系统管理员");
System.out.println(username+"是否有系统管理员的角色:"+hasRole2);//true
//权限
boolean permitted1 = subject.isPermitted("user:query");
System.out.println(username+"是否有user:query的权限:"+permitted1);//true
boolean permitted2 = subject.isPermittedAll("user:query","user:export");
System.out.println(username+"是否有同时拥有user:query和user:export的权限:"+permitted2);//
}else{
System.out.println("未登陆");
}
}
三,自定义授权角色信息
1, 继承AuthorizingRealm抽象类,重写doGetAuthorizationInfo方法
//做权限认证
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//得到用户对象
ActiveUser activeUser = (ActiveUser) principals.getPrimaryPrincipal();
//获得用户角色
List<String> roles = activeUser.getRoles();
//获得用户权限
List<String> permissions = activeUser.getPermissions();
//把当前的用户拥有的角色和权限告诉shrio
if(roles!=null && roles.size() >0){
info.addRoles(roles);
}
if(permissions != null && permissions.size() > 0){
info.addStringPermissions(permissions);
}
return info;
}
2,添加shiro配置文件,告诉系统自定义realm位置
#自定义realm
myrealm=com.yxt.realm.MyRealm
#指定securityManager的realms实现
securityManager.realms=$myrealm
3,加载配置文件,进行登录相关操作
//8.进行登录
try {
subject.login(token);//进行认证,如果失败会抛异常
System.out.println("登陆成功");
}catch (IncorrectCredentialsException e){
System.out.println("密码不正确");
}catch (UnknownAccountException e){
System.out.println("用户名不存在");
}catch (AuthenticationException e){
System.out.println("用户名或密码正确");
}
if(subject.isAuthenticated()){
boolean hasRole = subject.hasRole("超级管理员");
System.out.println(username+"是否有超级管理员的角色:"+hasRole);//false
boolean hasRole2 = subject.hasRole("系统管理员");
System.out.println(username+"是否有系统管理员的角色:"+hasRole2);//true
//权限
boolean permitted1 = subject.isPermitted("user:query");
System.out.println(username+"是否有user:query的权限:"+permitted1);//true
boolean permitted2 = subject.isPermittedAll("user:query","user:export");
System.out.println(username+"是否有同时拥有user:query和user:export的权限:"+permitted2);//
}else{
System.out.println("未登陆");
}
三,授权相关原理图
1.1 授权验证原理
1.2 rbac 概念图
四,解决注解式数据库手动添加权限的问题
1,在方法上添加权限
2, 自定义方法获取带有方法标注的权限将权限添加到数据库中