开源权限管理框架Shiro
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、Shiro基本概念:
Apache Shiro(日语“堡垒(Castle)”的意思)是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理功能,可为任何应用提供安全保障- 从命令行应用、移动应用到大型网络及企业应用。
Shiro为解决下列问题(我喜欢称它们为应用安全的四要素)提供了保护应用的API:认证- 用户身份识别,常被称为用户“登录”;
授权- 访问控制;
密码加密- 保护或隐藏数据防止被偷窥;
会话管理- 每用户相关的时间敏感的状态。
Shiro还支持一些辅助特性,如Web应用安全、单元测试和多线程,它们的存在强化了上面提到的四个要素。
Shiro的基本功能如图:
二、Shiro基本处理流程及一些主要概念
如图:
Shiro框架拦截到一个应用请求后,会为此请求建立一个Subject对象,本次Session没关闭时,Subject对象会一直存在,作为一个虚拟的user对象。对此对象可以进行身份验证(Authentication)和权限验证(Authorization),这些处理将会提交给Shiro的SecurityManager 对象。简单地理解,SecurityManager是一个总调度,负责接受不同的Subject对象的权限相关的处理请求。而真正干活的是Realm对象,也就是说最后作身份验证和权限验证的是Realm
对象。
Shiro的Realm对象不提供用户信息和权限信息,这些信息是Shiro的使用者要提供的,Realm中定义的各种验证方法和安全数据的容器,使用者是把自己的安全数据装进去。
重要的事情再说一遍,对subject的各种安全验证,使用者调用subject对象的相关属性和方法,不直接操作Realm对象。
三、一些简单的例子
为了帮助大家理解Shiro的运行机制,这里简单举例说明。假设我们有一个基于MVC 的简单web应用,假设Shiro框架已经配置好,拦截页面的任何请求(如何配置后面会简单介绍)。
1、登录时的身份验证:
(1)MVC中的C(controller)接收页面发来的登录请求,从request中取出页面送来的username, password。
java代码:
String username = request.getParameter("username");
String password = request.getParameter("password");
(2)构造token对象,装入username和password,用于验证。
java代码:
UsernamePasswordToken mytoken = new UsernamePasswordToken(username, password); (3)获取当前session的subject对象。
java代码:
Subject curSbj = SecurityUtils.getSubject();
(4)登录验证。
java代码:
curSbj.login(mytoken); 若login方法验证失败,会抛出异常,所以本方法应写在一个try catch结构中。
小结:只需要调用subject的方法,不直接访问realm。
2、在执行某个功能时判断当前用户是否有权限执行:
Subject curSbj = SecurityUtils.getSubject();
curSbj. isPermitted(“某权限”);
小结:只需要调用subject的方法,不直接访问realm。
3、判断当前用户是否具有某个角色:
Subject curSbj = SecurityUtils.getSubject();
curSbj.hasRole(“某角色”);
小结:只需要调用subject的方法,不直接访问realm。
4、Realm中怎样装入使用者自定义的权限数据
(1)调用curSbj.login(mytoken)方法的请求最终会被SecurityManager发送到realm对象,并调用realm对象的doGetAuthenticationInfo()方法,我们在这个方法中验证是否存在传入的
token中的username,并完成password验证。下面具体来看看doGetAuthenticationInfo()方法的代码。
java代码:
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
//下面这条语句就是你自己的业务,找到user对象,可以从数据库中取得,也可以从其他地方取得,总之下面的userservice就是你自己写的业务方法。
User u = userService.selectByUserName(token.getUsername());
if (u != null) {
return new SimpleAuthenticationInfo(u.getUserName(), u.getPassword(), getName());
}else{
throw new AuthenticationException();
}
}
那么,SecurityManager怎么找到realm对象呢?通常是通过配置文件配置的,后面会提供配置方法。
(2)调用curSbj.has Role(“某角色”) 方法的请求最终会被SecurityManager发送到realm对象,并调用realm对象的doGetAuthorizationInfo ()方法,我们在这个方法中取得用户的角色和权限。下面是具体的java代码:
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { /* 下面将构造两个set,一个装角色,一个装权限*/
Set
Set
User u = userService.selectByUserName5(principals.getPrimaryPrincipal().toString());
List
for (Role r:roles){
roleNames.add(r.getRoleCode());
}
List
for (Right ri:rights){
permissions.add(ri.getRightName());
}
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roleNames);
info.setStringPermissions(permissions);
return info;
}
四、Shiro里的一些基本概念
1、Subject、SecurityManager、Realm前面已经说明。
2、Principals:身份标识,可以有多个,例如用户名、手机号、邮箱地址等,我们在应用中