摘自http://www.open-open.com/home/space-53513-do-blog-id-5479.html
Shiro 是一个 Apache Incubator 项目,旨在简化身份验证和授权。本文只是我对shiro的初步认识,有不对的请大虾指正,谢谢!
基本概念
在对系统进行安全保障时,有两个安全性元素非常重要:身份验证和授权。虽然这两个术语代表的是不同的含义,但出于它们在应用程序安全性方面各自的角色考虑,它们有时会被交换使用。
身份验证 (我们平常接触较多的就是登录)指的是验证用户的身份。在验证用户身份时,需要确认用户的身份的确如他们所声称的那样。在大多数应用程序中,身份验证是通 过用户名和密码的组合完成的。只要用户选择了他人很难猜到的密码,那么用户名和密码的组合通常就足以确立身份。但是,还有其他的身份验证方式可用,比如指 纹、证书和生成键。
一旦身份验证过程成功地建立起身份,授权 (我理解的就是权限管理与控制)就会接管以便进行访问的限制或允许。所以,有这样的可能性:用户虽然通过了身份验证可以登录到一个系统,但是未经过授权,不准做任何事情。还有一种可能是用户虽然具有了某种程度的授权,却并未经过身份验证。
在为应用程序规划安全性模型时,必须处理好这两个元素以确保系统具有足够的安全性。身份验证是应用程序常见的问题(特别是在只有用户和密码组合的情 况下),所以让框架来处理这项工作是一个很好的做法。合理的框架可提供经过测试和维护的优势,让您可以集中精力处理业务问题,而不是解决其解决方案已经实 现的问题。
Apache Shiro 提供了一个可用的安全性框架,各种客户机都可将这个框架应用于它们的应用程序。本文中的这些例子旨在介绍 Shiro 并着重展示对用户进行身份验证的基本任务。
初识shiro
Shiro 是一个用 Java 语言实现的框架,通过一个简单易用的 API 提供身份验证和授权。使用 Shiro,您就能够为您的应用程序提供安全性而又无需从头编写所有代码。
由于 Shiro 提供具有诸多不同数据源的身份验证,以及 Enterprise Session Management,所以是实现单点登录(SSO)的理想之选 — 大型企业内的一个理想特性,因为在大型企业内,用户需要在一天内经常登录到并使用不同系统。这些数据源包括 JDBC、LDAP、 Kerberos 和 Microsoft® Active Directory® Directory Services (AD DS)。
Shiro 的 Session 对象允许无需 HttpSession 即可使用一个用户会话。通过使用一个通用的Session 对象,即便该代码没有在一个 Web 应用程序中运行,仍可以使用相同的代码。没有对应用服务器或 Web 应用服务器会话管理的依赖,您甚至可以在命令行环境中使用 Shiro。换言之,使用 Shiro 的 API 编写的代码让您可以构建连接到 LDAP 服务器的命令行应用程序并且与 web 应用程序内用来访问 LDAP 服务器的代码相同。
Shiro在Web中的应用
将shiro整合到Web中最简单的方式就是在web.xml文件中配置一个Servlet ContextListener的监听器和Filter过滤器。实例代码如下:
01 <listener>
02 <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
03 </listener>
04
05 ...
06
07 <filter>
08 <filter-name>ShiroFilter</filter-name>
09 <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
10 </filter>
11
12 <filter-mapping>
13 <filter-name>ShiroFilter</filter-name>
14 <url-pattern>/*</url-pattern>
15 </filter-mapping>
以上的配置是假定shiro.ini的配置文件是放在以下两个位置下的(哪个先找到就用哪个):
1. /WEB-INF/shiro.ini
2. classpath的根目录
以上的代码做了如下的工作:
EnvironmentLoaderListener初始化一个Shiro用的WebEnvironment实例(这个实例包括Shiro运行要用的任何东西,包含SecurityManager)并且让ServletContext可以访问它。可以在任何时刻调用WebUtils.getRequiredWebEnvironment(servletContext)语句获取WebEnvironment。
ShiroFilter将用WebEnvironment为所有的经过滤的request执行所有的安全保障操作。
最后,filter-mapping用以确保所有的请求通过ShiroFilter过滤。
注:建议将ShiroFilter filter-mapping声明在其他的filter-mapping声明之前,以确保Shiro也作用于那些filter。
Web INI 配置
默认情况下,初始化Shiro时,Shiro会自动按顺序搜索/WEB-INF/shiro.ini和classpath:shiro.ini位置下的.ini配置,然后用最先找到的那个。
如果配置较少,可以不用另外的.ini文件,而将INI配置在web.xml中。下面的配置就是将shiro的配置配置在web.xml中:
01 <tt><listener>
02 <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
03 </listener>
04
05 ...
06
07 <filter>
08 <filter-name>ShiroFilter</filter-name>
09 <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
10 <init-param>
11 <param-name>config</param-name>
12 <param-value>
13 [users]
14 # format: username = password, role1, role2, ..., roleN
15 User1 = 123456
16 Manager1 = 123456, Manager
17 [filters]
18 [urls]
19 /* = authc
20 </param-value>
21 </init-param>
22 </filter>
23
24 <filter-mapping>
25 <filter-name>ShiroFilter</filter-name>
26 <url-pattern>/*</url-pattern>
27 </filter-mapping></tt>
Web INI配置标准的有[main],[users],[roles],[urls]部分(具体如何配置可查看官方文档),下面是一个连接MySql数据库的配置示例:
01 [main]
02 ds = com.mysql.jdbc.jdbc2.optional.MysqlDataSource
03 ds.serverName = 127.0.0.1
04 ds.user = root
05 ds.password = root
06 ds.databaseName = test
07 ds.url = jdbc:mysql://127.0.0.1:3306/test
08 jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
09 jdbcRealm.permissionsLookupEnabled = true
10 jdbcRealm.authenticationQuery = SELECT password FROM ho_user WHERE name = ?
11 jdbcRealm.userRolesQuery = SELECT role FROM ho_user WHERE name = ?
12 jdbcRealm.permissionsQuery = SELECT permission FROM ho_user WHERE name = ?
13 jdbcRealm.dataSource = $ds
14
15 authc.loginUrl = /common/login.jsp
16 perms.unauthorizedUrl = /common/login.jsp
17 roles.unauthorizedUrl = /common/login.jsp
18
19 [urls]
20 /action/* = authc
21 /admin/**=authc,perms[high]
22 /system/**=authc,perms[high]
说明:
jdbcRealm.dataSource = $ds指定jdbcRealm的数据源是前面配置的数据库ds。
jdbcRealm.authenticationQuery,jdbcRealm.userRolesQuery,jdbcRealm.permissionsQuery 配置行是jdbc的与查询语句,它告诉shiro从何处获取授权的配置。它们都是用查询后的记录的第一个字段进行验证 的,authenticationQuery是查询后取第一条记录的第一个字段(这里是password字段)进行验证;userRolesQuery是用查询后的第一个字段(这里是role字段)作为所属的角色的(可以有多条记录即多个角色);permissionsQuery同userRolesQuery一样查询后可以有多条记录,但也是取第一个字段作为权限字符串。
authc.loginUrl = /common/login.jsp是指定如果验证失败则页面跳转到/common/login.jsp下,perms.unauthorizedUrl = /common/login.jsproles.unauthorizedUrl = /common/login.jsp同理。
[urls] 里的配置就是对特定的url进行授权。/admin/**=authc,perms[high],是对匹配/admin/**的url配置权限,进入此 url须通过authc和perms[high]验证(authc和perms都是系统内置的过滤器。authc告诉shiro,进入此url,必须是已 验证的登录用户;perms[high] 是权限限定符,perms是内置的过滤器,high是通过jdbcRealm.permissionsQuery查询出来的权限字符串,只有用户拥有该字 符串的权限,才能获得访问授权。如果针对角色授权,可以是/admin/**=authc,roles[admin])。
附内置过滤器:
过滤器名
类
anon
org.apache.shiro.web.filter.authc.AnonymousFilter
authc
org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authcBasic
org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
logout
org.apache.shiro.web.filter.authc.LogoutFilter
noSessionCreation
org.apache.shiro.web.filter.session.NoSessionCreationFilter
perms
org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
port
org.apache.shiro.web.filter.authz.PortFilter
rest
org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
roles
org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
ssl
org.apache.shiro.web.filter.authz.SslFilter
user
org.apache.shiro.web.filter.authc.UserFilter
Shiro应用
配置好Web INI后,就能将其应用在Web中了,我们可以看看有了Shiro后,安全验证时多么的简便。
假设有一个LoginAction,只需三句语句就能实现验证
01 public String execute() throws Exception {
02 try {
03 AuthenticationToken token = new UsernamePasswordToken(username,password);//username和password是从表单提交过来的
04 Subject currentUser = SecurityUtils.getSubject();
05 currentUser.login(token);
06 return SUCCESS;
07 }catch (Exeception e){
08 Return ERROR;
09 }
10 }
只需两句话就能实现LogoutAction的动作
1 public String execute() throws Exception {
2 Subject currentUser = SecurityUtils.getSubject();
3 currentUser.logout();
4 return SUCCESS;
5 }
注:SecurityUtils 对象是一个 singleton,这意味着不同的对象可以使用它来获得对当前用户的访问。一旦成功地设置了这个SecurityManager,就可以在应用程序不同部分调用SecurityUtils.getSubject() 来获得当前用户的信息。
补充说明:
上述代码中用到了Subject和UsernamePasswordToken。这里增加一点Shiro的概念。
Subject 是安全领域术语,除了代表人,它还可以是应用。在单应用中,可将其视为 User 的同义词。
Principal 是 Subject 的标识,一般情况下是唯一标识,比如用户名。
用户令牌。在 Shiro 术语中,令牌 指的是一个键,可用它登录到一个系统。最基本和常用的令牌是 UsernamePasswordToken,用以指定用户的用户名和密码。UsernamePasswordToken 类实现了AuthenticationToken 接口,它提供了一种获得凭证和用户的主体(帐户身份)的方式。UsernamePasswordToken 适用于大多数应用程序,并且您还可以在需要的时候扩展AuthenticationToken 接口来将您自己获得凭证的方式包括进来。例如,可以扩展这个接口来提供您应用程序用来验证用户身份的一个关键文件的内容。
更多的认证用法,请参考官方文档。
更多的授权用法,请参考官方文档。
JSP/GSP标签库
Shiro提供了JSP/GSP的标签库,这使得我们很容易能够在JSP,JSTL或GSP页面的控制基于Subject的状态的输出。
标签库的描述符(Tag Library Descriptor (TLD))在shiro-web.jar 的META-INF/shiro.tld下定义。要引用这些标签,只需在JSP页面的头部添加下面的语句:
1 <tt><%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %></tt>
如定义一个pag_header.jsp如下:
01 <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
02 <div id="page_header">
03 <div id="page_heading">Hello World</div>
04 <div id="page_headerlinks">
05 <ul>
06 <li>
07 <shiro:guest>
08 <a href="/common/login.jsp">Login Now</a>
09 </shiro:guest>
10 <shiro:user>
11 Welcome, <shiro:principal />
12 </shiro:user>
13 </li>
14 <script>
15 var username = '<shiro:principal/>';
16 </script>
17 <li>
18 <shiro:guest>
19 <a href="/common/register.jsp">Register Now</a>
20 </shiro:guest>
21 <shiro:user>
22 <a href="Logout.action">Log out</a>
23 </shiro:user>
24 </li>
25 </ul>
26 </div>
27 <div class="clearthis"> </div>
28 </div>
说明:guest标签只用于显示当前Subject被认为是“guest”的Subject内容。通常用于显示没有登录的内容。user标签只用于 显示当前Subject被认为是“user”的Subject内容。通常用于显示已经登录的内容。一般情况下,两者是互斥的,只显其一。
更多标签用法,参见官方文档。
分享到:
相关推荐
无论是在命令行应用、移动应用还是大型网络和企业级应用中,Shiro都能发挥重要作用。 Shiro的核心功能包括: 1. **认证(Authentication)**:验证用户的身份,通常涉及用户登录过程。 2. **授权(Authorization)...
在 web 应用中,可以通过配置 `shiro.ini` 或者 `Web.xml` 来定制过滤器。 6. **Caching**:Shiro 支持缓存管理,可以缓存认证和授权信息,提高性能。 7. **Testing**:源码中包含了测试用例,帮助开发者理解和...
- 集成Shiro到Web应用中,通过过滤器实现对请求的权限检查,确保只有经过认证和授权的用户才能访问特定的资源。 #### 结论 Apache Shiro作为一个成熟且功能全面的安全框架,为Java开发者提供了强大的工具来构建...
- **Spring整合**:Shiro可以无缝集成到Spring应用中,利用Spring的依赖注入管理Shiro组件。 - **Web框架集成**:如Struts、Spring MVC等,通过拦截器实现Shiro的安全控制。 7. **学习资源** - **官方文档**:...
- **应用场景**:无论是简单的命令行应用还是大型集群Web应用,Shiro均能提供一致的安全支持。 通过以上详细解析,我们可以看到Apache Shiro 不仅是一款功能全面的安全框架,而且其设计上注重易用性和灵活性,非常...
- **SessionManager**:会话管理器,为任何类型的应用程序提供了一致的会话 API,无论是在小型后台独立应用还是大型集群 Web 应用中。这意味着开发者可以选择使用统一的会话 API,而不是受限于特定容器(如 Servlet ...
非常全面的介绍了shiro技术,希望对新接触这方面的同学有帮助。
Apache Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能。 使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
Apache Shiro是一个全面的Java安全框架,...总之,理解Apache Shiro的RememberMe机制以及其反序列化漏洞对于保障Web应用程序的安全至关重要。开发者应时刻关注软件的安全更新,并采取必要的措施来保护用户的敏感信息。
本文将深入探讨Shiro的基本概念、核心架构以及如何在实际应用中使用。 首先,我们来理解两个关键的安全概念:身份验证和授权。身份验证是确认用户身份的过程,通常通过用户名和密码的组合实现。而授权则是确定验证...
在实际应用中,我们可能还会涉及到以下方面: 1. Realm配置:根据实际的数据存储(如数据库、LDAP)创建自定义Realm,实现AuthenticationInfo和AuthorizationInfo的获取。 2. 过滤器链设置:定义哪些URL需要经过哪些...
Shiro 是一个 Apache Incubator 项目,旨在简化身份验证和授权。在本文中,了解 Apache Shiro 并通过示例来在一个 Groovy web 应用程序中尝试使用 Shiro 进行身份验证和授权
在Web应用中,MySQL通常用于存储用户信息、业务数据等。它支持SQL标准,具有高性能、高可用性和可扩展性。在Spring MVC和Apache Shiro的环境中,开发者可以通过JDBC或MyBatis等持久化框架与MySQL进行交互,执行CRUD...
在实际应用中,Shiro 过滤器链配置是关键,它定义了请求如何被不同过滤器处理。 6. **Remember Me 功能**:Shiro 的 Remember Me 功能允许用户在一段时间内无须再次登录,提高了用户体验。这通常通过在客户端存储...
总之,整合Apache Oltu和Apache Shiro创建的轻量级OAUTH2应用框架,为Web应用和移动设备的安全提供了坚实的基础。通过合理的配置和扩展,开发者可以轻松地实现身份验证、授权和OAuth2的无缝集成,提高应用的安全性。
5. Web支持(Web Support):Shiro提供了一套API来帮助保护Web应用程序,例如过滤器和相关的Web安全机制。 6. 缓存(Caching):缓存机制是Shiro的核心特性之一,用来提高安全操作的性能和效率。 7. 并发...
5. **Web支持**:Shiro提供了一系列过滤器,可以直接集成到Servlet容器中,实现Web应用的安全控制,如登录检查、权限验证等。 6. **测试支持**:Shiro提供了安全测试工具,使得在单元测试和集成测试中模拟用户身份...
4. **会话管理**:Shiro 可以管理应用中的会话,包括会话创建、读取、更新、删除以及超时处理等。此外,它还支持分布式会话,适用于多服务器环境。 5. **Web 应用安全**:Shiro 集成了 Web 应用安全特性,如过滤器...
本系统(基于SpringBoot+MyBatis+Apache Shiro+Bootstrap+Thymeleaf) 可用于开发所有企业级WEB应用系统(如:各种后台管理系统、CRM、ERP、CMS、OA、博客、论坛等...)。响应式布局,支持大部分浏览器(如:IE9+...
在安全性方面,Shiro提供了对Web应用的安全指导,包括如何用Shiro来保护你的应用程序。此外,Shiro的缓存管理器提供了高效的数据缓存能力,有利于提升应用性能。Shiro还包含了一系列加密功能,提供了数据加密、密码...