`
guoyiqi
  • 浏览: 1002629 次
社区版块
存档分类
最新评论

Apache Shiro在Web中的应用

 
阅读更多

概述

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.iniclasspath: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.jarMETA-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内容。通常用于显示已经登录的内容。一般情况下,两者是互斥的,只显其一。

更多标签用法,参见官方文档

分享到:
评论
1 楼 ilemma 2012-07-24  
我也是刚参见工作啊,经理让自学这个,有些东西不太懂,能不能发个源码啊...不胜感激...dilemma_gpf@foxmail.com

相关推荐

    Apache shiro 1.13.0源码

    在 web 应用中,可以通过配置 `shiro.ini` 或者 `Web.xml` 来定制过滤器。 6. **Caching**:Shiro 支持缓存管理,可以缓存认证和授权信息,提高性能。 7. **Testing**:源码中包含了测试用例,帮助开发者理解和...

    让Apache Shiro保护你的应用

    2. **广泛的适用范围**:Shiro能够满足各种类型应用的安全需求,无论是Web应用、移动应用还是企业级应用,都可以通过Shiro实现一站式安全解决方案。 3. **高度灵活**:Shiro的设计不受特定容器或框架的限制,可以在...

    Apache Shiro教程

    通过这个Apache Shiro教程,你可以学习到如何构建安全的Java应用,了解Shiro的配置和用法,以及如何在实际项目中实施身份验证、授权、会话管理和加密策略。无论你是初学者还是经验丰富的开发者,Shiro都是一个值得...

    Apache Shiro中文开发文档.pdf

    - **应用场景**:无论是简单的命令行应用还是大型集群Web应用,Shiro均能提供一致的安全支持。 通过以上详细解析,我们可以看到Apache Shiro 不仅是一款功能全面的安全框架,而且其设计上注重易用性和灵活性,非常...

    Apache_Shiro_使用手册(一)Shiro架构介绍

    Shiro 可以广泛应用于各种类型的 Java 应用程序中,无论是 Web 应用、桌面应用还是服务端应用。其灵活性使得开发者可以根据项目的具体需求选择适当的组件进行集成。 - **Web 应用**:Shiro 可以为 Web 应用提供强大...

    让Apache_Shiro保护你的应用.pdf

    - 集成Shiro到Web应用中,通过过滤器实现对请求的权限检查,确保只有经过认证和授权的用户才能访问特定的资源。 #### 结论 Apache Shiro作为一个成熟且功能全面的安全框架,为Java开发者提供了强大的工具来构建...

    Apache shiro1.2.4反序列化漏洞介绍.docx

    Apache Shiro是一个全面的Java安全框架,...总之,理解Apache Shiro的RememberMe机制以及其反序列化漏洞对于保障Web应用程序的安全至关重要。开发者应时刻关注软件的安全更新,并采取必要的措施来保护用户的敏感信息。

    Apache Shiro核心jar包:shiro-core-1.3.2

    Apache Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能。 使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。

    Apache Shiro 集成-spring

    总的来说,Apache Shiro与Spring的集成可以让我们在Spring的环境中充分利用Shiro的安全功能,为应用程序提供全面的安全保障。通过理解和实践这些知识点,开发者可以构建更加安全可靠的Java应用。

    apache shiro maven包

    Shiro 是一个 Apache Incubator 项目,旨在简化身份验证和授权。在本文中,了解 Apache Shiro 并通过示例来在一个 Groovy web 应用程序中尝试使用 Shiro 进行身份验证和授权

    spring mvc、apache shiro、mysql 框架搭建,基于maven构建

    在Web应用中,MySQL通常用于存储用户信息、业务数据等。它支持SQL标准,具有高性能、高可用性和可扩展性。在Spring MVC和Apache Shiro的环境中,开发者可以通过JDBC或MyBatis等持久化框架与MySQL进行交互,执行CRUD...

    在 Web 项目中应用 Apache Shiro

    非常全面的介绍了shiro技术,希望对新接触这方面的同学有帮助。

    apache shiro 实例

    5. **Web 支持**:Shiro 提供了处理 Web 应用安全的特性,如过滤器,可以方便地集成到 Servlet 容器中,实现登录、权限控制等功能。在实际应用中,Shiro 过滤器链配置是关键,它定义了请求如何被不同过滤器处理。 6...

    使用Apache Shiro保护你的WEB应用

    无论是小型的命令行工具,还是大型的企业级Web应用,Shiro都能提供相应的安全防护。由于其灵活性和简洁性,越来越多的开发者选择Shiro作为他们的安全解决方案,尤其是当他们已经使用了Spring框架时,Shiro也成为了...

    apache shiro文档

    通过学习这些文档,你不仅可以掌握 Apache Shiro 的基本用法,还能深入了解其在实际项目中的应用,提升你在权限控制领域的专业技能。对于开发人员来说,理解并熟练运用 Shiro,能有效地提高应用的安全性和用户体验。

    shiro jar包及源码下载

    5. **Web支持**:Shiro提供了一系列过滤器,可以直接集成到Servlet容器中,实现Web应用的安全控制,如登录检查、权限验证等。 6. **测试支持**:Shiro提供了安全测试工具,使得在单元测试和集成测试中模拟用户身份...

    Apache_Shiro参考手册中文版

    5. Web支持(Web Support):Shiro提供了一套API来帮助保护Web应用程序,例如过滤器和相关的Web安全机制。 6. 缓存(Caching):缓存机制是Shiro的核心特性之一,用来提高安全操作的性能和效率。 7. 并发...

    shiro1.7.1.zip

    2. **shiro-web-1.7.1.jar**:这个模块是针对Web环境设计的,提供了Web相关的安全控制,如Filter配置、HTTP请求的拦截处理等,方便在Web应用中集成Shiro。 3. **shiro-lang-1.7.1.jar**:Shiro的语言支持模块,可能...

    整合Apache Oltu 与 Shiro. 提供一个轻量的OAUTH2应用框架

    Apache Oltu和Apache Shiro都是在IT领域中广泛使用的开源项目,它们分别专注于身份验证、授权和OAuth2协议的实现。将这两个组件整合在一起,可以构建出一个强大的、轻量级的安全应用框架,适用于各种应用场景,包括...

Global site tag (gtag.js) - Google Analytics