一、入门程序
1.授权流程
2.授权的三种方式
(1)编程式: 通过写if/else 授权代码块完成。
Subject subject = SecurityUtils.getSubject();
if(subject.hasRole("admin")) {
//有权限
} else {
//无权限
}
(2)注解式: 通过在执行的Java方法上放置相应的注解完成。
@RequiresRoles("admin")
public void hello() {
//有权限
}
(3)JSP/GSP 标签: 在JSP/GSP 页面通过相应的标签完成。
<shiro:hasRole name="admin">
<!— 有权限—>
</shiro:hasRole>
3.ini文件
shiro-permission.ini
在ini文件中用户、角色、权限的配置规则是:“用户名=密码,角色1,角色2...” “角色=权限1,权限2...”,首先根据用户名找角色,再根据角色找权限,角色是权限集合。
资源标识符:操作:资源实例标识符”,意思是对哪个资源的哪个实例具有什么操作,“:”是资源/操作/实例的分割符,权限字符串也可以使用*通配符。
例子:
用户创建权限: user:create,或user:create:*
用户修改实例001的权限: user:update:001
用户实例001的所有权限: user:*:001
4.测试代码
/*
* 授权的测试
*/
public class AuthorzationTest{
//角色授权、资源授权测试
@Test
public void testAuthorzation(){
//创建SecurityManager工厂
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-permission.ini");
//创建SecurityManager
SecurityManager securityManager = factory.getInstance();
//将SecurityManager设置到系统环境
SecurityUtils.setSecurityManager(securityManager);
//创建Subject
Subject subject = SecurityUtils.getSubject();
//创建token令牌
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","123");
//执行认证
try{
subject.login(token);
}catch(AuthenticationException e){
e.printStackTrace();
}
System.out.println("是否认认证通过: " + subject.isAuthenticated());
//基于角色的授权(角色标识)
boolean hasRole = subject.hasRole("role3");
System.out.println("基于角色的授权: " + hasRole);
//基于资源的授权(权限标识符)
boolean permitted = subject.isPermitted("user:create");
System.out.println("基于资源的授权: " + permitted);
}
}
结果:
是否认认证通过: true
基于角色的授权: false
基于资源的授权: true
二、自定义Realm
1.shiro-realm.ini
在shiro-realm.ini中配置自定义的realm,将realm设置到securityManager中。
2.实现代码
/*
* 自定义Realm
*/
public class CustomRealm extends AuthorizingRealm{
//设置Realm名称
@Override
public void setName(String name){
super.setName("customRealm");
}
//用于认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException{
//1.从token取出用户身份信息
String userCode = (String)token.getPrincipal();
//2.根据用户userCode查询数据库
//模拟从数据库查询到的密码
String password = "123";
//3.查询到返回认证信息
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(userCode,password,this.getName());
return info;
}
//用于授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals){
//获取主身份信息
String userCode = (String)principals.getPrimaryPrincipal();
//根据身份信息获取权限信息
//模拟从数据库获取到数据
List<String> permissions = new ArrayList<String>();
permissions.add("user:create"); //用户的创建权限
permissions.add("items:add"); //商品的添加权限
//将查询到授权信息填充到对象中
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addStringPermissions(permissions);
return info;
}
}
3.测试代码
@Test
public void testCusRealm(){
//创建SecurityManager工厂
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-realm.ini");
//创建SecurityManager
SecurityManager securityManager = factory.getInstance();
//将SecurityManager设置到系统环境
SecurityUtils.setSecurityManager(securityManager);
//创建Subject
Subject subject = SecurityUtils.getSubject();
//创建token令牌
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","123");
//执行认证
try{
subject.login(token);
}catch(AuthenticationException e){
e.printStackTrace();
}
System.out.println("是否认认证通过: " + subject.isAuthenticated());
//基于资源的授权(权限标识符)
boolean permitted = subject.isPermitted("user:create");
System.out.println("基于资源的授权: " + permitted);
}
越努力,越幸运!