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

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中文开发文档.pdf

    Shiro 视图在所有应用程序环境下实现这些目标——从最简单的命令行应用程序到最大的企业应用,不强制依赖其 他第三方框架,容器,或应用服务器。当然,该项目的目标是尽可能地融入到这些环境,但它能够在任何环境下...

    让Apache Shiro保护你的应用

    Apache Shiro(发音为“shee-roh”,日语“堡垒(Castle)”的意思)是一个强大易用的Java安全框架,提供了认证、...Shiro还支持一些辅助特性,如Web应用安全、单元测试和多线程,它们的存在强化了上面提到的四个要素

    apache shiro maven包

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

    在 Web 项目中应用 Apache Shiro

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

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

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

    SpringBoot+MyBatis+Apache Shiro+Bootstrap+Thymeleaf可用于开发企业级应用系统

    本系统(基于SpringBoot+MyBatis+Apache Shiro+Bootstrap+Thymeleaf) 可用于开发所有企业级WEB应用系统(如:各种后台管理系统、CRM、ERP、CMS、OA、博客、论坛等...)。响应式布局,支持大部分浏览器(如:IE9+...

    使用Apache Shiro保护你的WEB应用

    Apache Shiro是一个Apache项目...与JAAS和Spring Security比较,Apache Shiro在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势。本文介绍了Apache Shiro的基础知识和核心架构,同时给出了一个典型使用示例。

    Apache_Shiro参考手册中文版.zip

    该尽可能掩盖复杂的地方,露出一个干净而直观的 API,来简化开发人员在使他们的应用程序安全上的努力。 以下是你可以用 Apache Shiro 所做的事情:  验证用户来核实他们的身份  对用户执行访问控制,如:  判断...

    apache-shiro-tutorial-webapp:分步教程,显示如何使用Apache Shiro保护Web应用程序

    apache-shiro-webapp-tutorial 介绍了如何使用Apache Shiro保护Web应用程序。

    Apache Shiro安全框架-其他

    Apache Shiro具有出色的Web应用程序支持,允许您基于应用程序URL和Web协议(例如REST)创建灵活的安全策略,同时还提供一组JSP库来控制页面输出。 可插拔 Shiro干净的API和设计模式使它易于与许多其他框架和应用程序...

    Apache-Shiro-中文参考文档.docx

    框架应该尽可能掩盖复杂的地方,露出一个干净而直观的 API,来简化开发人员在使他们的应用程序安全上的努力。 以下是你可以用 Apache Shiro 所做的事情: • 验证用户来核实他们的身份 • 对用户执行访问控制,如:...

    Apache Shiro 身份认证例子- Web应用

    可直接拷贝到Tomcat下运行,默认用户名/口令:admin/admin

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

    整合Apache Oltu 与 Shiro. 提供一个轻量的OAUTH2应用框架。并根据不同的应用场景提供不同的实现(如web场景,移动设备).

    ShiroSamples:Apache Shiro示例

    可以使用Apache Shiro做的一些事情:验证用户身份用户访问控制,例如:确定用户是否被分配了某个安全角色确定用户是否被允许做某件事在任何环境中使用会话API,甚至无需使用web或EJB容器React认证,访问控制或会话的...

    shiro 1.4.0所有jar包(全)

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

    Apache-Shiro-使用手册

    Apache-Shiro-使用手册 Apache Shiro 是一个框架,可用于身份验证和授权。本文提供了几个示例用来展示如何在 Java™ 应用程序中使用 Shiro 并给出了如何在一个 Grails web 应用程序中使用它的概述。

    shiro 1.4.1.rar

    Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在 JavaSE 环境,也可以用在 JavaEE 环境。Shiro 可以帮助我们完成:认证、授权、加密、会话管理、与 Web 集成、缓存等。这不就是我们想要的嘛,而且 Shiro 的...

    Apache_Shiro

    该尽可能掩盖复杂的地方,露出一个干净而直观的API,来简化开发人员在使他们的应用程序安全上的努力。 以下是你可以用Apache Shiro 所做的事情: . 验证用户来核实他们的身份 . 对用户执行访问控制,如: . 判断用户...

    shiro-site:Apache Shiro网站

    Apache Shiro网站概述Apache Shiro网站是静态内容网站,可以从访问。 网站内容被创作为Markdown和HTML文件。 这些文件由工具扫描,该工具根据需要将页面模板应用于每个文件的内容,并将呈现的静态.html文件输出到...

Global site tag (gtag.js) - Google Analytics