改章节朋友在青岛游玩的时候突然想到的...这两天就有想写几篇关于文件用户的博客,所以回家到之后就奋笔疾书的写出来发表了
Apache Shiro官网:http://shiro.apache.org/
念概:
shiro是一个大强活灵的源开安全架框,可以干净利落的处置证认、授权、企业话会理管和加密。
shiro的要首标目是简略和易于解理。安全有时候是非常庞杂使人头疼的问题,shiro隐藏了庞杂
的细节,暴露了简介直观的API来简化开发者使他们的应用程序更安全的尽力。
功能:停止用户证认、执行问访控制、单点登录、Remember Me服务
安全的一些念概:身份证认、授权、话会理管、加密被认为是形成应用安全的础基要素。
身份证认,就是验证用户身份,型典的“登录”程过就是身份证认的程过。
授权:也就是问访控制(ac),也即某用户可以可以应用应用的哪些功能?
会议理管:理管用户特定的话会,即使在非Web或EJB应用。
加密:坚持据数的安全应用的加密算法,同时仍然易于应用。
对于Session,在WEB应用中它基于HttpSession,而一般应用中认默应用企业话会理管。shiro的Session
用起来和HttpSession差不多,并且应用它不要需Http环境。
在最高的层次上讲,shiro要主有三个要主的念概,它们分别是Subject、SecurityManager和Realms。
1、shiro应用Subject这一念概来述描当前用户,‘User’这个词平日隐含的指一个人,但是Subject可所以一个
人也可以代表第三方服务,护守户账,时定业作,或者其他相似的与软件互交的事物。
2、有所Subject例实都与一个SecurityManager绑定,当你和一个Subject互交时,有所互交会都通过SecurityManager
转换为特定Subject的互交。
SecurityManager是shiro架构的核心,它演扮‘保护伞’象对的色角,与其他外部安全组件一同形成象对图的核心。
SecurityManager及其内贸部象对图一旦被应用置配,它基本上就被放在一边不再被程序员应用了,
开发人员基本上总是在与Subject的相干API打交道。它在幕后支撑Subject的安全操作。
3、Realms在shiro与你的应用程序的安全据数之间充当着桥梁或者说是接连器的作用。
从这类意义上讲,Reaml就是一个特定的安全DAO,它为shiro供提所需的据数。
在置配shiro时,你必须为证认、授权指定少至一个可用的Realm。
shiro供提了现成的Realm接连到LDAP、关系据数库(JDBC)、ini和properties文件等。
用户可以应用自己的Realm
Shiro 是一个用 Java 言语现实的架框,通过一个简略易用的 API 供提身份验证和授权。应用 Shiro,您就够能为您的应用程序供提安全性而又无需从头编写有所码代。
Shiro 的 Session
象对答应无需 HttpSession
便可应用一个用户话会。通过应用一个通用的 Session
象对,即便该码代没有在一个 Web 应用程序中运行,仍可以应用同相的码代。没有对应用服务器或 Web 应用服务器话会理管的依附,您甚至可以在令命行环境中应用 Shiro。换言之,应用 Shiro 的 API 编写的码代让您可以构建接连到 LDAP 服务器的令命行应用程序并且与 web 应用程序内用来问访 LDAP 服务器的码代同相。由于 Shiro 供提拥有诸多不同据数源的身份验证,以及 Enterprise Session Management,所所以现实单点登录(SSO)的想理之选 — 大型企业内的一个想理特性,因为在大型企业内,用户要需在一天内经常登录到并应用不同系统。这些据数源含包 JDBC、LDAP、 Kerberos 和 Microsoft® Active Directory® Directory Services (AD DS)。
Shiro 是预构建的二进制发行版。您可以下载 Shiro JAR 文件或将各项放入到 Apache Maven 或 Apache Ivy 来自动装安这些文件。本例应用 Ivy 下载 Shiro JAR 文件以及其他所要需的库,脚本很简略,如清单 1 所示。
1. Apache Ivy 文件和 Apache Ant 脚本
<?xml version="1.0" encoding="UTF-8"?> <ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd"> <info organisation="com.nathanagood.examples" module="shirotest" /> <configurations> <conf name="dist" description="Dependency configuration for distribution." /> </configurations> <dependencies> <dependency org="commons-logging" name="commons-logging" rev="1.1.1" conf="dist->default" /> <dependency org="org.slf4j" name="slf4j-log4j12" rev="1.5.8" conf="dist->default" /> <dependency org="org.apache.shiro" name="shiro-core" rev="1.0.0-incubating" conf="dist->default" /> <dependency org="org.apache.shiro" name="shiro-web" rev="1.0.0-incubating" conf="dist->default" /> </dependencies> </ivy-module> <project name="shiroTestApp" default="usage" basedir="." xmlns:ivy="antlib:org.apache.ivy.ant"> <property name="project.lib" value="lib" /> <path id="ivy.task.path"> <fileset dir="${basedir}/ivy-lib"> <include name="**/*.jar" /> </fileset> </path> <target name="resolve"> <taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant" classpathref="ivy.task.path" /> <ivy:resolve /> <ivy:retrieve pattern="${project.lib}/[conf]/[artifact].[ext]" sync="true" /> </target> <target name="usage"> <echo message="Use --projecthelp to learn more about this project" /> </target> </project> |
有关应用 Ivy 的更多信息,拜见 参考资料。如果应不用 Maven 或 Ivy,可用从本文 参考资料 分部供提的下载站点下载这些 Shiro JAR 文件。
下载了这些库后,只要将它们添加到 CLASSPATH。编写 清单 2 内所示的简略码代,它得获对当前用户的一个引用并呈文说用户未经身份验证。(应用 Subject
类来代表此用户。)
package com.nathanagood.examples.shirotest; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.config.IniSecurityManagerFactory; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.Factory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ShiroTest { private static Logger logger = LoggerFactory.getLogger(ShiroTest.class); public static void main(String[] args) { // Using the IniSecurityManagerFactory, which will use the an INI file // as the security file. Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("auth.ini"); // Setting up the SecurityManager... org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); Subject user = SecurityUtils.getSubject(); logger.info("User is authenticated: " + user.isAuthenticated()); } } |
添加了此码代后,建创一个名为 auth.ini 的文件。此时,这个文件是空白的;它的作用只是为了够能在这里运行这个示例来检查码代否是畸形作工。
建创文件后,运行这个示例。应该会看到含包了一个 INFO 登录消息的输出,呈文说用户没有登录。
SecurityUtils
象对是一个 singleton,这意味着不同的象对可以应用它来得获对当前用户的问访。一旦胜利地设置了这个SecurityManager
,就能够在应用程序不同分部用调 SecurityUtils.getSubject()
来得获当前用户的信息。
在 Shiro 术语中,令牌 指的是一个键,可用它登录到一个系统。最基本和经常使用的令牌是 UsernamePasswordToken
,用以指定用户的用户名和码密。
UsernamePasswordToken
类现实了 AuthenticationToken
接口,它供提了一种得获凭证和用户的主体(帐户身份)的方法。UsernamePasswordToken
适于用大多数应用程序,并且您还可以在要需的时候扩展 AuthenticationToken
接口来将您自己得获凭证的方法含包进来。例如,可以扩展这个接口来供提您应用程序用来验证用户身份的一个键关文件的内容。
至此,这个简略的示例涵盖的内容含包:动启 Shiro SecurityManager
、得获当前用户并记载下用户未经身份验证。接下来的这个例子将会应用 UsernamePasswordToken
和存储在 INI 文件内的一个用户记载来展示如何通过用户名和码密停止身份验证。
清单 3 内所示的 auth.ini 文件当初含包了一个用户记载;这个记载含包了用户名和码密。您可以在这个记载内定义色角以及为应用程序供提授权。
[users] bjangles = dance |
当初,建创 前一节 中分析的这个 UsernamePasswordToken
象对,如 清单 4 所示。
清单 4. 应用 UsernamePasswordToken 类
// snipped... same as before. public class ShiroTest { private static Logger logger = LoggerFactory.getLogger(ShiroTest.class); public static void main(String[] args) { // Using the IniSecurityManagerFactory, which will use the an INI file // as the security file. Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("auth.ini"); // Setting up the SecurityManager... org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); Subject user = SecurityUtils.getSubject(); logger.info("User is authenticated: " + user.isAuthenticated()); UsernamePasswordToken token = new UsernamePasswordToken("bjangles", "dance"); user.login(token); logger.info("User is authenticated: " + user.isAuthenticated()); } } |
UsernamePasswordToken
象对由用户名和码密的合组例实化。随后,令牌被递传至 Subject
类的 login()
方法。
再次运行这个示例。注意到登录消息当初呈文说此用户已身份验证。
要确保码代畸形作工且得获的不是一个误报,在码代内改更码密或改更这个 INI 文件并再次运行此示例。login()
方法当初会抛出一个 IncorrectCredentialsException
。在产生码代内这个常异应被明白捕获以便应用程序在用户供提了不确正的码代时够能停止适当的响应。
如果用户不确正,login()
方法就会抛出一个 UnknownAccountException
。我们既要斟酌如何处置这个常异,但又应不向用户供提太多信息。一种见常的做法是不要向用户示提用户名有效、只有码密不确正。这是因为如果有人试图通过测猜得获问访,那么您绝对不会想要表示这人他所测猜的用户名是确正的。
LDAP 是用来在 TCP/IP 上查询目录的一种协议。这些目录可保存有关用户的恣意数量的信息,含包用户 ID、联系信息以及组成员等。LDAP 目录对于公司的通讯簿很有效并被泛广应用。
AD DS 是一种于用用户和组理管的见常目录,它支撑 LDAP。 Shiro 不含包通用的 LDAP 安全域,但它却含包了一个ActiveDirectoryRealm
象对,答应针对 LDAP 停止用户的身份验证。本例应用了在 INI 文件内置配的 ActiveDirectoryRealm
象对来验证用户的身份。虽然 AD DS 与 LDAP 不同,但本文中应用的 Shiro 的这个本版并没有自带通用的 LDAP 象对。
让一个 LDAP 服务器来测试本例要比编写并运行示例本身要需更多作工。如果您不能问访一个 AD DS 服务器,那么可以斟酌下载并装安 Apache Directory 来供提一个 LDAP 服务器的例样现实。Apache Directory 是用 Java 言语编写的。同样地,Apache Active Directory Studio 是一个 Eclipse 插件,可用来览浏 LDAP 据数。它还拥有一些例样据数,为您供提了一种快捷方法来针对已知值编写码代,而又无需惑疑您到遇的问题是码代问题还是据数问题。
清单 5 表现了用来对存储在 Apache Directory 内的一个用户停止身份验证所需的码代。
// snipped... public class ShiroLDAPTest { private static Logger logger = LoggerFactory.getLogger(ShiroLDAPTest.class); /** * @param args */ public static void main(String[] args) { // Using the IniSecurityManagerFactory, which will use the an INI file // as the security file. Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("actived.ini"); // Setting up the SecurityManager... org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); Subject user = SecurityUtils.getSubject(); logger.info("User is authenticated: " + user.isAuthenticated()); UsernamePasswordToken token = new UsernamePasswordToken( "cn=Cornelius Buckley,ou=people,o=sevenSeas", "argh"); user.login(token); logger.info("User is authenticated: " + user.isAuthenticated()); } } |
除了 INI 文件名和用户名及码密以外,码代与之前用 INI 文件内的记载停止身份验证的码代同相。这类相似性的现出是因为您可以应用 INI 文件来置配 Shiro。用来设置 Shiro 针对 Apache Directory 停止身份验证的这些 INI 记载如 清单 6 所示。
[main] activeDirectoryRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm activeDirectoryRealm.systemUsername = uid=admin,ou=system activeDirectoryRealm.systemPassword = secret activeDirectoryRealm.searchBase = o=sevenSeas,ou=people activeDirectoryRealm.url = ldap://localhost:10389 |
注意: 我应用 Apache Directory Studio 来将用户的码密改更为一个能放入测试码代以确保它作工的值。
您可以应用两种基本技能将 Shiro 应用到 web 应用程序。首先,您可以应用这个 API 来将这里所展示的的码代并入一个础基 servlet。其次,您可以应用 Shiro 自带的 HTTP 过滤器。本例展示了第二种技能,因为应用过滤器充分利用了内置 web 应用服务器技巧以及来自 Shiro 目项的先预编写好的码代。
本例表现了如何应用 Grails 内的这些过滤器。Grails 是一个目项,旨在让您通过应用一种例惯优先则原(convention-over-configuration)的方法尽快地编写 Groovy web 应用程序。有关 Grails 的更多信息,请拜见 参考资料。
对于 Shiro 过滤器,您平日会手动地向 web.xml 文件添加需必的过滤器项。但是,Grails 会在您每次动启应用程序时生成 web.xml 文件,因此不必手动修改 web.xml。
荣幸的是,Grails 供提了插件,可集成到 web.xml 生成程过并会让您也可以与参在 web.xml 文件内编写这些项。如今,Grails 的可用插件很多,含包面向 Shiro 的这个插件。议建实验应用这个 Shiro Grails 插件,它供提了几个新的脚本,运行这些脚本可以建创不同的域和控制器。
或者,如果您更违心自己添加这些项并停止置配,您也可以编写您自己的插件。对于 Grails,编写一个新的插件很易容。要建创能将需必的 Shiro 过滤器项添加到 web.xml 文件的 Grails 插件,可以应用如下令命:
> grails create-plugin ShiroWebXml |
建创了这个插件目项后,编辑 ShiroWebXmlPlugin.groovy 文件,并添加如 清单 7 所示的码代。
class ShiroWebXmlPlugin { // snipped plugin details... def doWithWebDescriptor = { xml -> def filterElement = xml.'filter' def lastFilter = filterElement[filterElement.size() - 1] lastFilter + { 'filter' { 'filter-name'("ShiroFilter") 'filter-class'("org.apache.shiro.web.servlet.IniShiroFilter") 'init-param' { 'param-name'("config") 'param-value'("\n#config") } } } def filterMappingElement = xml.'filter-mapping' def lastFilterMappingElement = filterMappingElement[filterMappingElement.size() - 1] lastFilterMappingElement + { 'filter-mapping' { 'filter-name'("ShiroFilter") 'url-pattern'("/*") } } } } |
当 Grails 执行这个 web.xml 文件时,此码代就会运行。
在动启这个插件应用程序测试它之前,先将用 Ivy 下载的 Shiro JAR 文件复制到此插件的 lib 文件夹。有了 JAR 文件后,用以下令命测试此插件否是能畸形作工:
grails run-app |
如果此插件应用程序胜利动启,您可以将它打包以便用在一个示例目项中。要打包这个插件,应用如下令命:
grails package-plugin |
可以用如下令命装安这个新的 ShiroWebXmlPlugin
:
cd myapp grails install-plugin /path/to/shiro-web-xml-1.0.zip |
如果现出了 UnavailableSecurityManagerException
,那么是能可 SecurityManager
未被确正设置。在用调 getSubject()
方法之前,请确保它设在 SecurityUtils
象对上。
接连到 LDAP 服务器可能会有些难困。如果失掉一个 javax.naming.CommunicationException
,那么请检查此 LDAP 服务器的主机名和端口。即便您没有应用 Apache Directory,Apache Directory Studio(可独单装安)也可以帮助您消除接连障故以及名称问题。
如果您没有应用 Ant Ivy 脚来本初始化您的环境,那么有可能会失掉丧失类的误错。即便没有 Apache Commons Logging library (commons-logging
),这个 INI 文件示例仍可运行,但是运行这个 LDAP 示例会致使一个常异。这时,可以应用 Apace CommonsBeanUtils
来析解这个 INI 文件并设置象对上的值。
Shiro 是 Apache Incubator 内的一个架框,可以让您向应用程序中添加身份验证和授权。它支撑不同的身份验证存储方法,比如 LDAP
文章结束给大家分享下程序员的一些笑话语录:
人工智能今天的发展水平:8乘8的国际象棋盘其实是一个体现思维与创意的强大媒介。象棋里蕴含了天文数字般的变化。卡斯帕罗夫指出,国际象棋的合法棋步共有1040。在棋局里每算度八步棋,里面蕴含的变化就已经超过银河系里的繁星总数。而地球上很少有任何数量达到这个级别。在金融危机之前,全世界的财富总和大约是1014人民币,而地球人口只有1010。棋盘上,所有可能的棋局总数达到10120,这超过了宇宙里所有原子的总数!经典语录网