一、Maven工程导入shiro的坐标:
<!-- 导入shiro的坐标 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
shiro底层依赖commons-logging包,如果不导入会报错
二、自定义realm,继承AuthorizingRealm后,实现两个方法,一个是授权方法:获取授权信息,一个是认证方法:获取认证信息
public class MyRealm extends AuthorizingRealm{
//授权方法:获取授权信息
@Override
protected AuthorizationInfodoGetAuthorizationInfo(PrincipalCollection arg0) {
return null;
}
//认证方法:获取认证信息
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0)
throwsAuthenticationException {
return null;
}
}
三、建立配置文件shiro.ini,使SecurityManager 关联Realm
myRealm=cn.hezhiyu.realms.MyRealm
securityManager.realm=$myRealm
四、shiro认证流程
public class Demo1 {public static void main(String[] args) {
//1.创建安全管理器工厂
Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//2.创建安全管理器
SecurityManager securityManager = factory.getInstance();
//3.初始化SecurityUtils工具类
SecurityUtils.setSecurityManager(securityManager);
//4.从SecurityUtils工具中获取Subject
Subject subject = SecurityUtils.getSubject();
//5.认证操作(登录)
//AuthenticationToken: 用于封装用户输入的账户信息
AuthenticationToken token = new UsernamePasswordToken("jack", "1234");
try {
subject.login(token);
//获取SimpleAuthenticationInfo的第一个参数:principal
Object principal = subject.getPrincipal();
//如果login方法没有任何异常,代表认证成功
System.out.println("登录成功:"+principal);
} catch (UnknownAccountException e) {
//账户不存在
System.out.println("账户不存在");
} catch (IncorrectCredentialsException e) {
//密码错误
System.out.println("密码错误");
} catch (Exception e) {
//系统错误
System.out.println("系统错误");
}
}
}
五、在Realm(MyRealm 类)编写认证的逻辑
//认证方法
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throwsAuthenticationException {
System.out.println("执行认证方法...");
//判断用户名或密码
//1.获取用户输入的账户信息
UsernamePasswordToken token =(UsernamePasswordToken)arg0;
String username = token.getUsername();
//2.模拟数据库的账户信息
String name = "jack";
String password = "1234";
if(!username.equals(name)){
returnnull; // shiro底层自动抛出UnknownAccountException
}
/**
* 参数一:principal,用于把数据回传到 login 方法
* 参数二:数据库的密码
* Shiro 底层对比密码的结果:
* 1)密码正确:认证通过
* 2)密码不正确:自动抛出 IncorrectCredentialsException
* 参数三:realm 的名称,只有在多个 realm 的是才会使用
*/
return new SimpleAuthenticationInfo("callback",password,"");
}
六、shiro的授权操作shiro的授权分两种:基于资源的授权(必须得到资源的授权码才可以访问该资源)基于角色的授权(必须得到该角色,才可以访问该资源) 要进行授权操作,必须先进行shiro的认证
基于资源的授权
//进行 Shiro 的授权
//1.基于资源的授权
//判断当前登录用户是否有“商品添加”功能
//isPermitted():返回 true,有权限, false:没有权限
System.out.println("productAdd="+subject.isPermitted("productAdd"));
Realm 的授权方法:
//授权方法:获取授权信息
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
System.out.println("执行授权方法...");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//资源授权码
info.addStringPermission("productAdd");
return info;
}
//2.基于角色的授权
//判断当前登录用户是否为“超级管理员”
System.out.println("admin="+subject.hasRole("admin"));
//授权方法:获取授权信息
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
System.out.println("执行授权方法...");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//资源授权码
//info.addStringPermission("productAdd");
//进行通配符授权
info.addStringPermission("product:*");
//角色授权码
info.addRole("admin");
return info;
}
代码:
public class Demo2 {
public static void main(String[] args) {
//1.创建安全管理器工厂
Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//2.创建安全管理器
SecurityManager securityManager = factory.getInstance();
//3.初始化SecurityUtils工具类
SecurityUtils.setSecurityManager(securityManager);
//4.从SecurityUtils工具中获取Subject
Subject subject = SecurityUtils.getSubject();
//5.认证操作(登录)
//AuthenticationToken: 用于封装用户输入的账户信息
AuthenticationToken token = new UsernamePasswordToken("jack", "1234");
try {
subject.login(token);
//获取SimpleAuthenticationInfo的第一个参数:principal
Object principal = subject.getPrincipal();
//如果login方法没有任何异常,代表认证成功
System.out.println("登录成功:"+principal);
//进行Shiro的授权
//1.基于资源的授权
//判断当前登录用户是否有“商品添加”功能
//isPermitted():返回true,有权限, false:没有权限
System.out.println("productAdd="+subject.isPermitted("product:add"));
System.out.println("productUpdate="+subject.isPermitted("product:update"));
//2.基于角色的授权
//判断当前登录用户是否为“超级管理员”
System.out.println("admin="+subject.hasRole("admin"));
} catch (UnknownAccountException e) {
//账户不存在
System.out.println("账户不存在");
} catch (IncorrectCredentialsException e) {
//密码错误
System.out.println("密码错误");
} catch (Exception e) {
//系统错误
System.out.println("系统错误");
}
}
}
编写 Realm授权方法:
//授权方法
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
System.out.println("ִ执行授权方法...");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//资源的授权码
//info.addStringPermission("productAdd");
//通配符的授权
info.addStringPermission("product:*");
//角色的授权码
info.addRole("admin");
return info;
}