本文共 6762 字,大约阅读时间需要 22 分钟。
Shiro 是一个 Apache Incubator 项目,旨在简化身份验证和授权。本文只是我对shiro的初步认识,有不对的请大虾指正,谢谢!
在对系统进行安全保障时,有两个安全性元素非常重要:身份验证和授权。虽然这两个术语代表的是不同的含义,但出于它们在应用程序安全性方面各自的角色考虑,它们有时会被交换使用。
身份验证 指的是验证用户的身份。在验证用户身份时,需要确认用户的身份的确如他们所声称的那样。在大多数应用程序中,身份验证是通过用户名和密码的组合完成的。只要用户选择了他人很难猜到的密码,那么用户名和密码的组合通常就足以确立身份。但是,还有其他的身份验证方式可用,比如指纹、证书和生成键。
一旦身份验证过程成功地建立起身份,授权 就会接管以便进行访问的限制或允许。所以,有这样的可能性:用户虽然通过了身份验证可以登录到一个系统,但是未经过授权,不准做任何事情。还有一种可能是用户虽然具有了某种程度的授权,却并未经过身份验证。
在为应用程序规划安全性模型时,必须处理好这两个元素以确保系统具有足够的安全性。身份验证是应用程序常见的问题(特别是在只有用户和密码组合的情况下),所以让框架来处理这项工作是一个很好的做法。合理的框架可提供经过测试和维护的优势,让您可以集中精力处理业务问题,而不是解决其解决方案已经实现的问题。
Apache 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中最简单的方式就是在web.xml文件中配置一个Servlet ContextListener的监听器和Filter过滤器。实例代码如下:
... org.apache.shiro.web.env.EnvironmentLoaderListener ShiroFilter org.apache.shiro.web.servlet.ShiroFilter ShiroFilter /*
以上的配置是假定shiro.ini的配置文件是放在以下两个位置下的(哪个先找到就用哪个):
1. /WEB-INF/shiro.ini
2. classpath的根目录
以上的代码做了如下的工作:
注:建议将ShiroFilter filter-mapping声明在其他的filter-mapping声明之前,以确保Shiro也作用于那些filter。
默认情况下,初始化Shiro时,Shiro会自动按顺序搜索/WEB-INF/shiro.ini和classpath:shiro.ini位置下的.ini配置,然后用最先找到的那个。
如果配置较少,可以不用另外的.ini文件,而将INI配置在web.xml中。下面的配置就是将shiro的配置配置在web.xml中:
... org.apache.shiro.web.env.EnvironmentLoaderListener ShiroFilter org.apache.shiro.web.servlet.ShiroFilter config [users] # format: username = password, role1, role2, ..., roleN User1 = 123456 Manager1 = 123456, Manager [filters] [urls] /* = authc ShiroFilter /*
Web INI配置标准的有[main],[users],[roles],[urls]部分(具体如何配置可查看),下面是一个连接MySql数据库的配置示例:
[main] ds = com.mysql.jdbc.jdbc2.optional.MysqlDataSourceds.serverName = 127.0.0.1ds.user = rootds.password = rootds.databaseName = testds.url = jdbc:mysql://127.0.0.1:3306/testjdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealmjdbcRealm.permissionsLookupEnabled = truejdbcRealm.authenticationQuery = SELECT password FROM ho_user WHERE name = ?jdbcRealm.userRolesQuery = SELECT role FROM ho_user WHERE name = ?jdbcRealm.permissionsQuery = SELECT permission FROM ho_user WHERE name = ?jdbcRealm.dataSource = $dsauthc.loginUrl = /common/login.jspperms.unauthorizedUrl = /common/login.jsproles.unauthorizedUrl = /common/login.jsp[urls]/action/* = authc/admin/**=authc,perms[high]/system/**=authc,perms[high]
说明:
附内置过滤器:
过滤器名 | 类 |
anon | |
authc | |
authcBasic | |
logout | |
noSessionCreation | |
perms | |
port | |
rest | |
roles | |
ssl | |
user |
配置好Web INI后,就能将其应用在Web中了,我们可以看看有了Shiro后,安全验证时多么的简便。
假设有一个LoginAction,只需三句语句就能实现验证
public String execute() throws Exception { try { AuthenticationToken token = new UsernamePasswordToken(username,password);//username和password是从表单提交过来的 Subject currentUser = SecurityUtils.getSubject(); currentUser.login(token); return SUCCESS; }catch (Exeception e){ Return ERROR; }}
只需两句话就能实现LogoutAction的动作
public String execute() throws Exception { Subject currentUser = SecurityUtils.getSubject(); currentUser.logout(); return SUCCESS;}
注:SecurityUtils
对象是一个 singleton,这意味着不同的对象可以使用它来获得对当前用户的访问。一旦成功地设置了这个SecurityManager
,就可以在应用程序不同部分调用SecurityUtils.getSubject()
来获得当前用户的信息。
补充说明:
上述代码中用到了Subject和UsernamePasswordToken
。这里增加一点
Shiro
的概念。
UsernamePasswordToken
,用以指定用户的用户名和密码。UsernamePasswordToken
类实现了AuthenticationToken
接口,它提供了一种获得凭证和用户的主体(帐户身份)的方式。UsernamePasswordToken
适用于大多数应用程序,并且您还可以在需要的时候扩展AuthenticationToken
接口来将您自己获得凭证的方式包括进来。例如,可以扩展这个接口来提供您应用程序用来验证用户身份的一个关键文件的内容。更多的认证用法,请参考。
更多的授权用法,请参考。
Shiro提供了JSP/GSP的标签库,这使得我们很容易能够在JSP,JSTL或GSP页面的控制基于Subject的状态的输出。
标签库的描述符(Tag Library Descriptor (TLD))在shiro-web.jar 的META-INF/shiro.tld下定义。要引用这些标签,只需在JSP页面的头部添加下面的语句:
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
如定义一个pag_header.jsp如下:
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
说明:guest标签只用于显示当前Subject被认为是“guest”的Subject内容。通常用于显示没有登录的内容。user标签只用于显示当前Subject被认为是“user”的Subject内容。通常用于显示已经登录的内容。一般情况下,两者是互斥的,只显其一。
更多标签用法,参见。
, Apache;
,;
,;
,。
转载请注明出处!!!