GitHub:github.com/baiyuliang/…
上篇完成了登录验证及授权,那么对于授权的作用还没有体现出来,这篇就结合shiro权限标签来说说授权后有哪些用途?! 接上篇,登录成功后:
我们可以试着点击一下下面的几个模块,可能会出现4xx的错误,这是因为我们还没有添加路径映射:
@Configuration
public class AppConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//浏览器请求映射到对应页面(ViewName代表对应的html)
registry.addViewController("/").setViewName("login");
registry.addViewController("/login").setViewName("login");
registry.addViewController("/index").setViewName("index");
registry.addViewController("/reg").setViewName("reg");
registry.addViewController("user/userlist").setViewName("user/userlist");
registry.addViewController("user/add").setViewName("user/add");
registry.addViewController("user/edit").setViewName("user/edit");
registry.addViewController("/level1").setViewName("level1/index");
registry.addViewController("/level2").setViewName("level2/index");
registry.addViewController("/level3").setViewName("level3/index");
}
}
关于为什么都要添加映射,这里有个小坑...,就是在html页面使用shiro标签时,只有添加了映射的html页面才会有效(从shiro标签属性中获取用户信息)!另外,注意映射名不能与Controller中自己写的mappingurl冲突,比如我们之前可能在UserController中定了方法:
@RequestMapping("/user")
public class UserController {
@GetMapping("/{id}")
public User getUserById(@PathVariable Integer id) {
return userService.getUserById(id);
}
}
那么这个方法就会跟:
registry.addViewController("user/userlist").setViewName("user/userlist");
冲突!因为他们用了同样的路由“user”,系统无法识别你在调用时到底用的是哪个,就会报错!(系统默认先从UserController访问,比如你输入http://xxx/user/userlist 时会提示你数据类型不对,不能传入字符串类型)
现在,如果我们使用admin登录的(user,role,permission三表大家要配置好,能提现不同角色差异即可),此时我们打开权限测试1、2、3模块都能正常打开,因为我们在ShiroConfig已经为相应角色分配了页面访问权限:
map.put("/level1/**", "anyRoleFilter[user,admin,superadmin]");
map.put("/level2/**", "anyRoleFilter[admin,superadmin]");
map.put("/level3/**", "anyRoleFilter[superadmin]");
level1下的资源,user,admin,superadmin角色都可以访问; level2下的资源,只有admin,superadmin角色可以访问; level3下的资源,只有superadmin角色可以访问;
目前,我数据库中的user表数据:
角色id分别为1(superadmin),2(admin),3(user)。
使用admin账号登录,那么打开的效果如图:
换账号baiyuliang,其角色为admin,权限测试1,2都没问题,但是打开3:
403,拒绝访问,好,我们再用一个只有user权限的用户test登录:
这说明我们配置的角色访问资源限制已经生效!现在打开用户管理模块:
如果出现错误,那可能是你没有写获取用户列表的接口:
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
User findByUsername(String username);
Page<User> findAll(Specification<User> spec, Pageable pageable);
}
public interface UserService extends BaseService {
User getUserByName(String username);
ResponseData getUserList(Integer page,Integer limit);
ResponseData logout();
}
@Override
public ResponseData getUserList(Integer page, Integer limit) {
ResponseData responseData = new ResponseData();
Specification<User> specification = (Specification<User>) (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
return cb.and(predicates.toArray(new Predicate[0]));
};
Pageable pageable = PageRequest.of(page - 1, limit);
Page<User> userPage = userRepository.findAll(specification, pageable);
responseData.setCode(1);
responseData.setMsg("获取用户列表成功");
responseData.setData(toList((int) userPage.getTotalElements(), userPage.getContent()));
return responseData;
}
@Override
public ResponseData logout() {
Subject subject = SecurityUtils.getSubject();
subject.logout();
return new ResponseData(1, "退出成功");
}
public Map<String, Object> toList(int total, List list) {
Map<String, Object> map = new HashMap<>();
map.put("list", list);
map.put("total", total);
return map;
}
注意getUserList方法是做了分页的,具体可以下载项目参考,不是本篇文章重点,所以不做过多说明!
继续查看上图,我们可以看到admin是有添加、编辑和删除操作权限的,我们可以继续切换baiyuliang和test账号测试:
看出差别了吗?superadmin角色可以添加、编辑和删除,admin角色可以添加、编辑而不能删除,user角色就只有查看权限了!
这个判断的具体流程是什么呢?
1.我们在Shiro授权方法中:
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
User user = (User) SecurityUtils.getSubject().getPrincipal();
Role role = roleService.getRoleById(user.getRoleId());
simpleAuthorizationInfo.addRole(role.getName());//角色:superadmin,admin,user
Permission permission = permissionService.getPermissionByRoleId(role.getId());;
simpleAuthorizationInfo.addStringPermission(permission.getName());//添加权限
return simpleAuthorizationInfo;
}
根据登录用户,给其添加了角色和对应权限!
2.在html页面中,引入shiro标签:
<html xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
3.在需要判断不同角色显示不同模块时,添加shiro标签如: shiro:hasAnyRoles="superadmin,admin":
<script type="text/html" id="toolbar">
<div class="layui-btn-container" shiro:hasAnyRoles="superadmin,admin">
<button class="layui-btn layui-btn-normal layui-btn-sm data-add-btn" lay-event="add">添加</button>
<button class="layui-btn layui-btn-sm layui-btn-danger data-delete-btn" lay-event="delete" shiro:hasRole="superadmin">删除
</button>
</div>
</script>
或shiro:hasRole="superadmin":
<a class="layui-btn layui-btn-xs layui-btn-danger data-count-delete" lay-event="delete" shiro:hasRole="superadmin">删除</a>
其实这里我只用了角色判断,关于shiro更多属性,可以看提示:
很容易理解吧,大家需要用到什么属性,就可以直接使用了!
<shiro:principal property="username"/>
principal就是显示登录用户信息的,里面的内容就是你在做Shiro验证时,所保存的信息:
我们保存的是user对象,那么取值的时候property对应user的属性即可!关于更多Shiro的使用及配置,以及shiro标签的使用,大家可以多参考文档了!