前言
Apache Shiro 是一个框架,可用于身份验证和授权。虽然这两个术语代表的是不同的含义,但出于它们在应用程序安全性方面各自的角色考虑,它们有时会被交换使用。
身份验证 指的是验证用户的身份。在验证用户身份时,需要确认用户的身份的确如他们所声称的那样。在大多数应用程序中,身份验证是通过用户名和密码的组合完成的。只要用户选择了他人很难猜到的密码,那么用户名和密码的组合通常就足以确立身份。但是,还有其他的身份验证方式可用,比如指纹、证书和生成键。
一旦身份验证过程成功地建立起身份,授权 就会接管以便进行访问的限制或允许。 所以,有这样的可能性:用户虽然通过了身份验证可以登录到一个系统,但是未经过授权,不准做任何事情。还有一种可能是用户虽然具有了某种程度的授权,却并未经过身份验证。
在为应用程序规划安全性模型时,必须处理好这两个元素以确保系统具有足够的安全性。身份验证是应用程序常见的问题(特别是在只有用户和密码组合的情况下),所以让框架来处理这项工作是一个很好的做法。合理的框架可提供经过测试和维护的优势,让您可以集中精力处理业务问题,而不是解决其解决方案已经实现的问题。
Apache Shiro 提供了一个可用的安全性框架,各种客户机都可将这个框架应用于它们的应用程序。本文中的这些例子旨在介绍 Shiro 并着重展示对用户进行身份验证的基本任务。
本文只针对Jeesite中shiro的用法进行整理,不会包括shiro环境配置和搭建等内容。
Jeesite中的shiro
2.1 spring-context-shiro.xml
spring-context-shiro.xml是shiro的主配置文件,配置信息是重点主要是安全认证过滤器的配置。它规定哪些url需要进行哪些方面的认证和过滤
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<!-- 安全认证过滤器 --> < bean id = "shiroFilter" class = "org.apache.shiro.spring.web.ShiroFilterFactoryBean" >
< property name = "securityManager" ref = "securityManager" />
< property name = "p" value = "${adminPath}/login" />
< property name = "successUrl" value = "${adminPath}" />
< property name = "filters" >
< map >
< entry key = "authc" value-ref = "formAuthenticationFilter" />
</ map >
</ property >
< property name = "filterChainDefinitions" >
< value >
/static/** = anon
/userfiles/** = anon
${adminPath}/login = authc
${adminPath}/logout = logout
${adminPath}/** = user
</ value >
</ property >
</ bean >
|
shiroFilter是shiro的安全认证过滤器,其中,
- securityManager:指定一个负责管理的bean,这个新的bean在接下来会定义,其中包含了认证的主要逻辑。
- loginUrl:没有登录的用户请求需要登录的页面时自动跳转到登录页面,不是必须的属性,不输入地址的话会自动寻找项目web项目的根目录下的”/login.jsp”页面。
- successUrl:登录成功默认跳转页面,不配置则跳转至”/”。如果登陆前点击的一个需要登录的页面,则在登录自动跳转到那个需要登录的页面。不跳转到此。
- unauthorizedUrl:没有权限默认跳转的页面。
- map中的entry指定了authc权限所对应的过滤器实体
而属性中的filterChainDefinitions则详细规定啦不同的url的对应权限
- anon:例子/admins/**=anon 没有参数,表示可以匿名使用。
- authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,没有参数
- roles:例子/admins/user/=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。
- perms:例子/admins/user/**=perms[user:add:],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/=perms["user:add:,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。
- rest:例子/admins/user/=rest[user],根据请求的方法,相当于/admins/user/=perms[user:method] ,其中method为post,get,delete等。
- port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString
是你访问的url里的?后面的参数。 - authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证
- ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https
- user:例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查
- 注:anon,authcBasic,auchc,user是认证过滤器,perms,roles,ssl,rest,port是授权过滤器
1
2
3
4
5
6
7
|
<!-- 定义 Shiro 主要业务对象 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <!-- <property name="sessionManager" ref="sessionManager" /> --> <property name="realm" ref="systemAuthorizingRealm" /> <property name="cacheManager" ref="shiroCacheManager" /> </bean> |
这部分代码定义了securitymanager的主要属性的实体,systemAuthorizingRealm和shiroCacheManager都是自己实现的,分别用于进行验证管理和cache管理。从配置文件能看出,配置文件指定了作为安全逻辑的几个结构,除了这两部分,还包括formAuthenticationFilter。其中realm和filter在com.thinkgem.jeesite.modules.sys.security包里实现。
2.2 FormAuthenticationFilter
从可见都逻辑上讲,FormAuthenticationFilter类是用户验证时所接触的第一个类。
当用户登录任意界面时,shiro会对当前状态进行检查。如果发现需要登录,则会自动跳转到配置文件里loginUrl属性所指定的url中。
而这一url又被指定为authc权限,即需要验证。接着,authc的filter被指定为formAuthenticationFilter,因此login页面所提交的信息被改filter截获进行处理。
其中的核心逻辑是createToken函数:
1
2
3
4
5
6
7
8
9
10
11
|
protected AuthenticationToken createToken(S2ervletRequest request, ServletResponse response) {
String username = getUsername(request);
String password = getPassword(request);
if (password== null ){
password = "" ;
}
boolean rememberMe = isRememberMe(request);
String host = getHost(request);
String captcha = getCaptcha(request);
return new UsernamePasswordToken(username, password.toCharArray(), rememberMe, host, captcha);
} |
UsernamePasswordToken是security包里的第四个类,它继承自shiro的同名类,用于shiro处理中的参数传递。createtoken函数接受到login网页所接受的表单,生成一个token传给下一个类处理。
函数中的rememberme以及captcha分别表示的是记住用户功能和验证码功能,这部分也是shiro自身携带,我们并不需要修改。filter是通过aop的方式结合到系统里的,因此并没有具体的接口实现。
2.3 SystemAuthorizingRealm
shiro的最终处理都将交给Real进行处理。因为在Shiro中,最终是通过Realm来获取应用程序中的用户、角色及权限信息的。通常情况下,在Realm中会直接从我们的数据源中获取Shiro需要的验证信息。可以说,Realm是专用于安全框架的DAO.
Realm中有个参数是systemService,这个便是spring的具体业务逻辑,其中也包含了具体的DAO,正是在这个部分,shiro与spring的接口具体的结合了起来。
realm当中有两个函数特别重要,分别是用户认证函数和授权函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
if (LoginController.isValidateCodeLogin(token.getUsername(), false, false)){
// 判断验证码
Session session = SecurityUtils.getSubject().getSession();
String code = (String)session.getAttribute(ValidateCodeServlet.VALIDATE_CODE);
if (token.getCaptcha() == null || !token.getCaptcha().toUpperCase().equals(code)){
throw new CaptchaException("验证码错误.");
}
}
User user = getSystemService().getUserByLoginName(token.getUsername());
if (user != null) {
byte[] salt = Encodes.decodeHex(user.getPassword().substring(0,16));
return new SimpleAuthenticationInfo(new Principal(user),
user.getPassword().substring(16), ByteSource.Util.bytes(salt), getName());
} else {
return null;
}
} |
以上便是用户认证函数,中间关于验证码检测的部分我们暂且不表,其最核心的语句是
1
2
3
|
User user = getSystemService().getUserByLoginName(token.getUsername()); 以及另一句语句 return new SimpleAuthenticationInfo(new Principal(user), user.getPassword().substring(16), ByteSource.Util.bytes(salt), getName()); |
函数的参数AuthenticationToken便是filter所截获并生成的token实例,其内容是login表单里的内容,通常是用户名和密码。在前一句话里,getSystemService取到了systemService实例,该实例中又含有配置好的userDAO,能够直接与数据库交互。因此将用户id传入,取出数据库里所存有的user实例,接着在SimpleAuthenticationInfo生成过程中分别以user实例的用户名密码,以及token里的用户名密码做为参数,验证密码是否相同,以达到验证的目的。
doGetAuthorizationInfo函数是授权的函数,其具体的权限是在实现类中以annotation的形式指派的,它负责验证用户是否有权限访问。详细的细节容我之后添加。
2.3 LoginController
LoginController是本该实现登录认证的部分。由于shiro的引入和AOP的使用,jeesite中的LoginController只处理验证之后的部分。
如果通过验证,系统中存在user实例,则返回对应的主页。否则重新定位于login页面。
2.4 annotation
常用的annotation主要如下:
-
@RequiresAuthentication
要求当前Subject 已经在当前的session 中被验证通过才能被注解的类/实例/方法访问或调用。
验证用户是否登录,等同于方法subject.isAuthenticated() 结果为true时。 -
@RequiresUser
需要当前的Subject 是一个应用程序用户才能被注解的类/实例/方法访问或调用。要么是通过验证被确认,或者在之前session 中的'RememberMe'服务被记住。
验证用户是否被记忆,user有两种含义:一种是成功登录的(subject.isAuthenticated() 结果为true);另外一种是被记忆的(subject.isRemembered()结果为true)。 -
@RequiresGuest
要求当前的Subject 是一个“guest”,也就是他们必须是在之前的session中没有被验证或记住才能被注解的类/实例/方法访问或调用。
验证是否是一个guest的请求,与@RequiresUser完全相反。
换言之,RequiresUser == !RequiresGuest。此时subject.getPrincipal() 结果为null. -
@RequiresRoles
要求当前的Subject 拥有所有指定的角色。如果他们没有,则该方法将不会被执行,而且AuthorizationException 异常将会被抛出。例如:@RequiresRoles("administrator")
或者@RequiresRoles("aRoleName");
void someMethod();
如果subject中有aRoleName角色才可以访问方法someMethod。如果没有这个权限则会抛出异常AuthorizationException。 -
@RequiresPermissions
要求当前的Subject 被允许一个或多个权限,以便执行注解的方法,比如:
@RequiresPermissions("account:create")
或者@RequiresPermissions({"file:read", "write:aFile.txt"} )
void someMethod();
3.相关网页
有一个简易的整体流程实现
http://blog.csdn.net/clj198606061111/article/details/24185023
对授权部分解释较为详细
http://sishuok.com/forum/posts/list/7456.html
相关推荐
在 Jeesite 框架中,Shiro 被用来实现用户登录验证和权限控制。以下是 Jeesite 使用 Shiro 进行登录验证和授权的主要流程的详细说明: 1. **前端登录处理**: - 用户通过 `syslogin.jsp` 页面输入用户名和密码,并...
这里会讲解如何在 Jeesite 中使用这些组件,以及相关的配置和调优技巧。 **6. 工作流的应用实例 (6.工作流的应用实例.docx)** Jeesite 集成了工作流引擎,支持业务流程自动化。此部分将通过具体案例介绍如何设计、...
在Jeesite中,Shiro为用户提供了统一的安全管理。 1. **身份验证**:Shiro可以对用户输入的凭证进行验证,确认用户身份。 2. **授权**:基于角色的权限控制,Shiro可以决定用户是否具有访问特定资源的权限。 3. **...
【标题】"基于jeesite的springmvc mybatis shiro html5项目" 是一个综合性的IT项目,它融合了多种技术栈,旨在构建一个现代化的企业级Web应用。这个项目的核心技术包括SpringMVC、MyBatis、Shiro以及HTML5,它们各自...
在"shiro角色管理框架讲解"这个主题中,我们将深入探讨Shiro如何处理角色管理和权限控制。 首先,Shiro的角色管理是基于角色的访问控制(RBAC)的核心部分。角色是一种抽象,代表了一组权限的集合。在Shiro中,我们...
shiro使用方法shiro使用方法shiro使用方法shiro使用方法
文档中的“Shiro的实用讲解”部分,可能会详细阐述Shiro的核心概念,如Subject、Realms、Session管理,以及如何在Jeesite中集成和使用Shiro进行权限控制。 5. **工作流Activiti**:Activiti是流行的业务流程管理...
在这个"shiro使用简单Demo"中,我们可以看到作者提供了一个基础的Shiro实现,特别针对URL和注解的权限管理进行演示,这对于初学者来说是一个很好的起点。 首先,我们来看`shiro2.xml`,这是Shiro的配置文件。在该...
1. **Subject**:Subject 是 Shiro 框架中的核心概念,它代表了当前进行操作的实体,可以是用户、第三方进程或者其他任何与系统交互的实体。Subject 提供了安全操作的接口,比如登录、登出、权限检查等。 2. **...
"shiro使用方法.ppt"则是关于Shiro更具体的用法介绍,可能会涵盖更复杂的应用场景,比如会话管理、记住我功能、CSRF防护等。此外,它可能还会涉及Shiro与其他技术的集成,如Spring框架,以及如何解决常见问题和调试...
在学习过程中,视频教程可能会从基础概念讲解到实际案例演示,逐步带你掌握如何配置Shiro,创建安全的登录流程,定义和分配权限,以及如何在实际项目中应用Shiro进行安全控制。同时,文档和源码分析将帮助你深入理解...
Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
jeesite代码生成,流程,菜单设置,shiro.doc
JeeSite框架是基于Spring Boot、MyBatis、Shiro等技术构建的企业级开发基础平台,集成了众多实用功能,包括权限控制、工作流等。 在使用JeeSite代码生成器之前,你需要按照一定的规则来准备数据库。例如,创建一个...
这本书籍详细介绍了Shiro框架的各个组件和使用方法。通过阅读,你可以了解到Shiro的基本架构,包括Subject、Realms、Caches等核心概念。Subject是Shiro中的核心接口,代表当前用户的安全上下文;Realms是数据源,...
在授权方面,Shiro 使用权限(Permission)、角色(Role)和用户(User)作为基础元素。权限表达式通常由冒号分隔,表示不同的操作范围。例如,`User:view` 表示用户查看权限,`User:view,edit` 表示用户有查看和...
在"shiro_tool.zip"这个压缩包中,我们可以推测可能包含了一些关于Shiro使用的工具类、配置示例或者是一些简化Shiro操作的实用代码。 Shiro的主要组件包括: 1. **认证**:验证用户身份的过程,即用户提交凭证(如...
6. **Web安全**:讲解如何在Web环境中使用Shiro,包括过滤器的配置和使用。 7. **实战案例**:提供实际项目中的应用场景和最佳实践。 然后是"shiro-example-master.zip"源码项目,这通常是一系列示例代码,展示了...
- API详解:详细介绍Subject、Realm、Session等核心接口及其使用方法。 - 配置指南:讲解如何配置Shiro以满足你的安全需求。 - 实战案例:分享一些实际应用场景,帮助你更好地理解Shiro的潜力。 - 故障排查:提供...
6. **Shiro API使用**: 在业务代码或控制器中,可以调用Subject的登出、认证、授权等方法。 **SSM与Redis和Shiro的整合** 1. **会话管理**: 通过Shiro的SessionManager,配置为使用Redis作为session的存储,实现...