1、自定义Realm
public class UserRealm extends AuthorizingRealm {
private StuServiceImpl stuService = new StuServiceImpl();
private RoleServiceImpl roleService = new RoleServiceImpl();
private PermissionServiceImpl permissionService = new PermissionServiceImpl();
@Override
public String getName() {
return this.getClass().getName().toString();
}
/**
* 认证,该方法只在认证的时候执行一次
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("doGetAuthenticationInfo");
String name = (String) authenticationToken.getPrincipal();
Stu stu = stuService.getStuByName(name);
// 密码到后期在判断,涉及加密相关
if(stu != null){
List<String> roles = roleService.getRoleByName(name);
List<String> permissions = permissionService.getPermissionByName(name);
ActiveStu activeStu = new ActiveStu(stu,roles,permissions);
// 构造方法第一个参数:任意对象
// 构造方法第二个参数:通常为密码
// 构造方法第三个参数:通常为当前类名
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(activeStu,stu.getPwd(),this.getName());
return info;
}
return null;
}
/**
* 授权,注意-->该方法会在每次进行授权操作的时候都执行一次
* 不能每次都去数据库查一次,解决方法有:
* 1、使用缓存,然后用aop切进来,判断是否有缓存
* 2、在认证成功后将权限传递过来
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("doGetAuthorizationInfo");
// getPrimaryPrincipal 就是获取在doGetAuthenticationInfo返回对象中的第一个构造方法参数
ActiveStu activeStu = (ActiveStu) principalCollection.getPrimaryPrincipal();
// SimpleAuthorizationInfo是AuthorizationInfo的子类
SimpleAuthorizationInfo info = info = new SimpleAuthorizationInfo();
// 判断是否为超级管理员
if(activeStu.getStu().getType() == 0){
info.addStringPermission("*:*");
info.addRole("*:*");
}else{
List<String> roles = activeStu.getRoles();
List<String> permissions = activeStu.getPermissions();
if(null != roles && roles.size() > 0){
info.addRoles(roles);
}
if(null != permissions && permissions.size() > 0){
info.addStringPermissions(permissions);
}
}
return info;
}
2、测试类
public class TestMyRealm {
public static void main(String[] args) {
// new一个Factory工厂
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
// 得到SecurityManager或其子类对象
DefaultSecurityManager securityManager = (DefaultSecurityManager) factory.getInstance();
// 设置自定义的Realm,设置后将不会读取ini文件的内容
UserRealm realm = new UserRealm();
securityManager.setRealm(realm);
// 设置到当前线程
SecurityUtils.setSecurityManager(securityManager);
// 得到subject对象
Subject subject = SecurityUtils.getSubject();
// 进行认证操作
String name = "zs";
String pwd = "123456";
try{
UsernamePasswordToken token = new UsernamePasswordToken(name,pwd);
subject.login(token);
System.out.println(name + " 是否登录成功:"+subject.isAuthenticated());
}catch (AuthenticationException e){
System.out.println("账号或密码错误!");
}
// 授权判断
boolean role1 = subject.hasRole("*:*");
System.out.println(name + " 是否具有 *:* 角色:"+role1);
boolean permitted = subject.isPermitted("*:*");
System.out.println(name + " 是否具有 *:* 权限:"+permitted);
}
}
结果
3、实体类
// 学生实体类
public class Stu {
private String name;
private String pwd;
// 0:超级管理员,1:普通用户
private int type;
public Stu(String name, String pwd,int type) {
this.name = name;
this.pwd = pwd;
this.type=type;
}
// get...set...
}
// 角色、权限、用户对象
public class ActiveStu {
private Stu stu;
private List<String> roles;
private List<String> permissions;
public ActiveStu(Stu stu, List<String> roles, List<String> permissions) {
this.stu = stu;
this.roles = roles;
this.permissions = permissions;
}
// get...set...
}
4、服务类
public class StuServiceImpl implements StuMapper {
public Stu getStuByName(String name) {
Stu stu = null;
// 模拟从数据库查询数据
if("zs".equals(name)){
stu = new Stu("zs","123456",0);
}else if("ls".equals(name)){
stu = new Stu("ls","123456",1);
}
return stu;
}
}
public class RoleServiceImpl implements RoleMapper {
public List<String> getRoleByName(String name) {
// 模拟从数据库查询数据
if("zs".equals(name)){
return Arrays.asList(new String[]{"role1","role2","role3"});
}else if("ls".equals(name)){
return Arrays.asList(new String[]{"role1"});
}
return null;
}
}
public class PermissionServiceImpl implements PermissionMapper {
public List<String> getPermissionByName(String name) {
// 模拟从数据库查询数据
if("zs".equals(name)){
return Arrays.asList(new String[]{"user:c","user:r","user:u","user:q"});
}else if("ls".equals(name)){
return Arrays.asList(new String[]{"user:c"});
}
return null;
}
}