欢迎光顾我的博客
开端
好的,起因是我把最近做好的项目给一部分人进行了测试,发现大部分朋友都提出了同一个问题,你的系统权限管理是如何实现的。我只能尴尬的说一句,不好意思这部分还没开发。然而我也知道,其实对于一个项目来说,权限可以说是最主要的一部分。后端除了对权限进行处理,其实也就是提供一些业务逻辑对 CRUD 进行组合拼装。所以我打算接下来学习权限控制方面的知识并整合到我的项目中去,顺便把我的学习笔记分享给大家。
而对于权限控制的框架呢,听的最多的还是 Shiro 还有 Spring Security。Spring 的安全框架单独用在 Spring 项目中是无可挑剔的,不管是功能上还是维护方面。但是考虑到 Shiro 是一个全能性的框架,可以用在各种场合,甚至非 Web 项目中,由于它的会话独立于容器,后期学习分布式和微服务的时候也比较方便使用。~~最重要的是 Spring 官网用的也是 Shiro 的框架。~~所以还是打算学习 Shiro。
由于这部分内容比较多,我也发现了前后端项目部署那篇文章接近 1w 字导致阅读的时候不是很舒服,所以我打算把这个内容分成几个部分:初识 Shiro、配置重点、整合技巧来讲述。这篇文章是关于初识 Shiro 的,主要是 Shiro 的一些基本特性和架构,以及官网上的小例子。
Shiro 简介
-
Apache 软件基金会开发的 Java 安全(权限)框架。
-
适用于 Java SE 和 Java EE 的环境。
-
主要功能有:认证、授权、加密、会话管理、集成 Web、缓存等。
Shiro 具体功能
功能 | 翻译 | 解释 |
---|---|---|
Authentication | 身份验证/登录 | 验证用户登录时的身份 |
Authorization | 权限验证 | 验证用户拥有哪些权限 |
Session Manager | 会话管理 | 一次登录即一次会话 |
Cryptography | 加密 | 保护数据安全,密码加密存储 |
Web Support | Web支持 | 支持方便的Web集成 |
Caching | 缓存 | 提高查找效率 |
Run As | 身份替换 | 假装成其他用户(若被允许) |
Remember Me | 二次记忆 | 二次登录无需验证 |
初次见面看不懂没有关系的,现在心中有个初步的印象,等到全部学习完整合完你就恍然大悟了。我就简单的讲两个:
Authentication
首先前两个功能比较容易混淆,到时候写程序千万看清别把方法名写错。Authentication 是身份的验证,我们对于权限的结构划分是基于 RBAC 模型来的(具体可以见我的另一篇博文),所以会有用户、角色、权限三层数据表。而这个功能就是判断用户的角色,是管理员、运维、开发还是测试等等。我们来看一段 Realm 中的方法 doGetAuthenticationInfo:
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
String userName = token.getUsername();
User user = userService.selectByName(userName);
return new SimpleAuthenticationInfo(
user.getUsrName(),
user.getUsrPassword(),
getName()
);
}
这段方法中首先获取用户身份 token 参数,然后获取用户名。使用我自定义的 Mapper 中的 selectByName( ) 在用户数据表中查询数据,最后返回一个 Simple 身份验证信息,参数为用户名、密码和 CachingRealm 的名字。当然正统的方式是把用户对象直接传给他,但是我测试的时候发现传用户名和密码出错的可能性更低,具体可以去看看 SimpleAuthenticationInfo 类的源码。
Authorization
第二个是用来验证角色所对应的权限。比如说管理员用户拥有增删改查所有权限,游客只拥有查找的权限等等。我们还是通过一段 Java 代码来理解这个功能。
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
String userName = (String)principalCollection.getPrimaryPrincipal();
if (userName == null) {
LOGGER.error("授权失败,用户信息为空!");
return null;
}