- 浏览: 1055343 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (279)
- Apache net (10)
- JBoss Rules (3)
- Seam ACL (1)
- Seam (14)
- Seam JPA高级权限验证 (8)
- 待解决的问题.... (1)
- JAVA (43)
- Dwr (4)
- Ajax4JSF (1)
- JavaScript (27)
- 生活小常识 (17)
- Richfaces (3)
- seam自己经历 (14)
- JDBC (1)
- mysql (6)
- WebService (10)
- Java Web (4)
- Hibernate (13)
- J2EE框架整合 (3)
- Spring (9)
- BEA Weblogic (1)
- XML (1)
- log4j (6)
- CSS (2)
- javaIO文件的读写 (5)
- SVN服务器的安装 (5)
- powerDesigner (2)
- SQL常用语句 (3)
- wicket初学 (5)
- eclipse (7)
- 正则表达式 (1)
- ExtJS (6)
- maven(m2eclipse) (1)
- struts2.0 (9)
- JPA (6)
- struts2.0整合spring2.5 (9)
- linux (6)
- Oracle (5)
- Servlet (3)
- MyEclipseGen (0)
最新评论
-
qq_31247573:
JAVA 获取http返回XML的数据 -
jasmine_20100810:
...
linux下tomcat服务的启动、关闭与错误跟踪 -
weiaiFang0624:
视频下载地址:http://download.csdn.net ...
there is no action mapped for namespace / and action name解决办法 -
p476462534:
JS控制表单form的提交 -
dandongsoft:
aaaaaaaaaaaaaaa
httpClient,JAVA访问http request response
15.3. 验证Seam安全中的验证特性是基于JAAS (Java Authentication and Authorization Service)开发的,它提供了用来进行用户身份认证的高度可配置的接口。然而,针对复杂多变的验证需求,Seam提供了一套非常简单的验证方法来隐藏JAAS的复杂性。
15.3.1. 配置一个验证组件注意: 如果你使用Seam的身份管理功能(稍后介绍),那么就不用特地建立一个验证组件(意味着你可以跳过这一章)。
这种简单的验证方法由Seam的一个内置的JAAS登录组件提供,叫做SeamLoginModule,它将验证功能转移到你自己编写的一个Seam组件之中。该登录模块已经作为Seam的默认程序规则设置好了,你不需要额外的配置文件。你可以在一个编写一个你自己的方法来进行验证,稍经修改也可以用来结合其他第三方程序进行验证。这些简单的配置需要在components.xml中添加一个identity组件:
<components xmlns="http://jboss.com/products/seam/components" xmlns:core="http://jboss.com/products/seam/core" xmlns:security="http://jboss.com/products/seam/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.1.xsd http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.1.xsd "> <security:identity authenticate-method="#{authenticator.authenticate}"/>components>
EL表达式#{authenticator.authenticate}绑定到验证组件的验证方法上,该方法被用来对登录的用户进行验证。
15.3.2. 编写验证方法components.xml文档中identity的authenticate-method属性指出SeamLoginModule将使用哪个方法来进行用户验证。该方法没有参数,并且返回值为boolean类型,用于判断登录是否成功。用户名和密码可以分别从Credentials.getUsername()和Credentials.getPassword()得到。用户所属的角色通过Identity.addRole()来添加。下面就是一个写在POJO组件中的完整验证方法:
@Name("authenticator") public class Authenticator { @In EntityManager entityManager; @In Credentials credentials; @In Identity identity; public boolean authenticate() { try { User user = (User) entityManager.createQuery( "from User where username = :username and password = :password") .setParameter("username", credentials.getUsername()) .setParameter("password", credentials.getPassword()) .getSingleResult(); if (user.getRoles() != null) { for (UserRole mr : user.getRoles()) identity.addRole(mr.getName()); } return true; } catch (NoResultException ex) { return false; } } }
在上面的例子中,User和UserRole都是实体。 roles属性包含了用户所拥有的角色,这个属性必须是一个字符串组成的Set,例如“admin”、“user”等。上面的程序中,如果符合条件的用户记录没有找到,那么抛出NoResultException 异常,验证失败,登录失败。
提示:当编写验证方法的时候,必须保证这个方法为最简的,因为Seam安全无法保证这个方法会被调用多少次,同一个请求中它可能被调用多次。因此,任一判断成功或失败之外的代码,应该写成实现an event observer。想要知道Seam安全所提交事件的更多信息,请参考后面的安全事件一章。
15.3.2.1. Identity.addRole()Identity.addRole()方法会根据当前session是否有效来执行不同的任务。如果当前session未经过验证,那么addRole()只会在验证过程中被调用。该方法被调用的时候,角色名称会被加入pre-authenticated的临时角色列表。一旦验证成功,pre-authenticated中的临时角色会变为真正的角色,并且在调用Identity.hasRole()的时候,会返回true。The following sequence diagram represents the list of pre-authenticated roles as a first class object to show more clearly how it fits in to the authentication process.
如果当前session通过验证,然后调用Identity.addRole(),就会立即将指定的角色赋予当前用户。
15.3.2.2. 编写一个与安全事件相关的observer让我们来讨论一个实际例子。当登录成功以后,一些用户数据需要被更新。这个功能可以通过编写一个事件观察器的方式来实现,通过监听org.jboss.seam.security.loginSuccessful事件,像这样:
@In UserStats userStats;@Observer("org.jboss.seam.security.loginSuccessful")public void updateUserStats() { userStats.setLastLoginDate(new Date()); userStats.incrementLoginCount();}
这个观察器方法可以放在任何地方,甚至是验证组件里面。你可以在后面的章节中找到更多关于安全事件的内容。
15.3.3. 编写一个登录表单credentials组件里面提供了username与password属性,符合绝大多数常用的用户登录验证情况。这些属性可以直接被绑定到登录表单的相关输入区上。一旦对这些属性进行了相关设定,那么调用identity.login()就会使用credentials对用户进行权限验证。下面就是一个简单的登录表单例子:
<div> <h:outputLabel for="name" value="Username"/> <h:inputText id="name" value="#{credentials.username}"/>div><div> <h:outputLabel for="password" value="Password"/> <h:inputSecret id="password" value="#{credentials.password}"/>div><div> <h:commandButton value="Login" action="#{identity.login}"/>div>
和登录类似,退出登录可以调用#{identity.logout}。调用这个方法会清除当前登录用户的登录状态,并且让当前用户的session失效。
15.3.4. 配置概述总的来说,配置登录验证,只需要三个步骤:
1、在components.xml中设置登录验证方法
2、编写一个登录验证方法
3、编写一个登录表单让用户可以有地方登录
15.3.5. 记住我Seam安全框架提供了一个类似“记住我”的功能,这个功能我们经常能在其他网站上看见。这个功能实际上是提供了两种不同的习惯或者模式。
第一种模式,浏览器将用户名通过cookie的方式保存下来,只保留密码文本框让用户填写(市面上常见的浏览器都提供了保存密码的功能)。
第二种模式,在cookie中保留用户的唯一性认证信息,允许用户下次登录网站的时候不用输入密码就能够自动通过登录权限验证。
警告
使用客户端的cookie记录用户信息,从而实现自动登录的方式是非常危险的。虽然你方便了客户,但是同时,你站点上的任何一个跨站点脚本安全漏洞都可能会造成严重的后果。如果没有登录验证cookie,那么黑客唯一能够通过XSS偷取的信息就只剩下当前用户的session了。这就意味着,只有当用户登录网站创建了一个session的一小段时间才可能被攻击。如果黑客能够通过“记住我”这个功能从保存在客户端的cookie中得到用户的帐号信息,那么他以后随时都能够以客户的身份通过登录验证。当然,你需要知道,前面说的这些攻击能否实现,也取决于你对XSS攻击做了哪些防范。如果你能够确保你的网站100%防御了XSS攻击,你完全可以让用户输入的数据全部都显示在页面上。只要你能够实现,这绝对是意见了不起的成就。
现在,几乎所有浏览器厂商都认识到了这个问题,并且提供了一个“保存密码”的功能。浏览器会为网站的一些页面,或者是一个domain保存用户的用户名和密码。这样用户在登录网站的时候,即使session未经过登录验证,浏览器也会自动将用户名密码填入指定的登录表单。网站的设计者可以放一个登录快捷键在页面上,然后让浏览器去记录用户名和密码,这样实现类似“记住我”的功能会更加安全。一些浏览器(例如Safari和OS X)甚至能够将用户的登录数据加密并保存在操作系统的密码表中。如果是在网络环境下,这个密码表还可以跟随用户到任何地方(例如从用户的台式机到笔记本)。而cookie在通常情况下是无法实现同步的。
总结:你最好在任何情况下都不要使用cookie来实现自动登录验证。不过,仅仅使用cookie来记住用户名,并且自动将保存的用户名填写进入表单中,就不会有太大的问题,同时也能在一定程度上方便用户。
如果想要默认打开“记住我”的功能(仅仅记住用户名),你不需要做任何额外的配置。只需要在登录表单中将记住我的复选框绑定到rememberMe.enabled,就像下面这个例子里面写的:
<div> <h:outputLabel for="name" value="User name"/> <h:inputText id="name" value="#{credentials.username}"/>div><div> <h:outputLabel for="password" value="Password"/> <h:inputSecret id="password" value="#{credentials.password}" redisplay="true"/>div><div class="loginRow"> <h:outputLabel for="rememberMe" value="Remember me"/> <h:selectBooleanCheckbox id="rememberMe" value="#{rememberMe.enabled}"/>div>
15.3.5.1. 基于特征的记住我验证如果你需要使用记住我功能中基于特征的自动验证模式,你首先需要配置一个特征仓库。最常见的方式就是将验证特征存储在一个数据库中(Seam支持的数据库)。你也可以通过实现org.jboss.seam.security.TokenStore接口的方式实现特征仓库。本节假设你使用使用一个虚拟的JpaTokenStore实现将验证需要用到的所有特征数据存储在数据库的一个表中。
首先你需要创建一个新的包含了tokens的Entity。下面这个例子展现了一种你可能用到的结构:
@Entitypublic class AuthenticationToken implements Serializable { private Integer tokenId; private String username; private String value; @Id @GeneratedValue public Integer getTokenId() { return tokenId; } public void setTokenId(Integer tokenId) { this.tokenId = tokenId; } @TokenUsername public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @TokenValue public String getValue() { return value; } public void setValue(String value) { this.value = value; }}
在上面的例子中,我们使用了一对特殊的注解,@TokenUsername和@TokenValue,它们用来指出实体的username和特征属性。这些注解标识了实体中需要用来验证的所有特征数据。
下一步就是配置JpaTokenStore,使用entity bean来存储或读取验证特征。具体的操作为,在components.xml中加入一个token-class属性:
<security:jpa-token-store token-class="org.jboss.seam.example.seamspace.AuthenticationToken"/>
然后,在components.xml加入RememberMe设置,并且将模式设置为autoLogin:
<security:remember-me mode="autoLogin"/>
通过上面这些设置,用户每次访问你的网站的时候就可以自动登录了(只要用户点击了“记住我”复选框)。
15.3.6. 处理安全异常在登录的时候难免出现异常,为了防止用户看见默认的错误页面,我们建议你在pages.xml里面配置一下页面自动跳转设置,这样就能够在出错的时候自动跳转到一些比较“漂亮”的页面上。最常见的两种安全异常为:
NotLoggedInException:这个异常在用户没有登录就尝试访问需要登录才能访问的页面的时候出现。
AuthorizationException:这个异常只出现在这种情况,用户已经登录了,并且访问某个页面,但是他并没有访问这个页面的权限。
在出现NotLoggedInException异常的情况下,我们建议将页面跳转到登陆页面或者注册页面
在出现AuthorizationException异常的时候,可以跳转到一个提示用户没有相应权限的页面。
下面是一个pages.xml文件的片段,这里面配置了这两种安全异常出现时的跳转规则:
<pages> ... <exception class="org.jboss.seam.security.NotLoggedInException"> <redirect view-id="/login.xhtml"> <message>You must be logged in to perform this actionmessage> redirect> exception> <exception class="org.jboss.seam.security.AuthorizationException"> <end-conversation/> <redirect view-id="/security_error.xhtml"> <message>You do not have the necessary security privileges to perform this action.message> redirect> exception>pages>
大部分web应用程序会需要更多的跳转规则,用以处理各种实际业务逻辑。所以Seam包含了一些特殊的功能用来处理这些问题。
15.3.7. 登录重定向当用户在没有登录的情况下试图访问某个需要登录才可以访问的页面(或者是一组用通配符指定的页面)的时候,Seam会将用户转到一个登录页面:
<pages login-view-id="/login.xhtml"> <page view-id="/members/*" login-required="true"/> ...pages>
当用户登录了以后,我们需要自动跳转到用户刚才未登录时尝试访问的页面。通过在components.xml中进行一下配置,就可以实现。并且跳转回刚才的页面的时候,所有的请求参数都会被保留。
<event type="org.jboss.seam.security.notLoggedIn"> <action execute="#{redirect.captureCurrentView}"/>event><event type="org.jboss.seam.security.postAuthenticate"> <action execute="#{redirect.returnToCapturedView}"/>event>
需要注意一下,登录跳转功能是基于会话范围实现的,所以不要在authenticate()方法中结束当前会话。
15.3.8. HTTP验证Seam也提供了HTTP Basic或HTTP Digest (RFC 2617)方式的验证。不过除非必要,我们不建议使用这些方式。在components.xml文件中,我们需要进行以下配置:
<web:authentication-filter url-pattern="*.seam" auth-type="basic"/>
如果需要使用digest验证方式,key和realm也需要设置一下:
<web:authentication-filter url-pattern="*.seam" auth-type="digest" key="AA3JK34aSDlkj" realm="My App"/>
key属性可以是任意值。realm为用户在登录的时候需要告诉用户的realm名称。
15.3.8.1. 编写Digest验证器当使用digest验证方式的时候,你的验证类需要集成自抽象类org.jboss.seam.security.digest.DigestAuthenticator,并且使用validatePassword()方法来验证用户的纯文本密码。例如:
public boolean authenticate() { try { User user = (User) entityManager.createQuery( "from User where username = :username") .setParameter("username", identity.getUsername()) .getSingleResult(); return validatePassword(user.getPassword()); } catch (NoResultException ex) { return false; }}
15.3.9. 高级验证特性本节将探索一些安全API中提供的高级验证特性,用来满足各种复杂的验证需求。
15.3.9.1. 使用容器的JAAS配置如果你不需要使用Seam Security API提供的简化了的JAAS配置,那么你可以将其委托给系统默认的JAAS配置。你可以通过在components.xml配置一个jaas-config-name来实现。例如,如果你使用JBoss AS,并且希望使用其他的验证策略(例如使用JBoss AS提供的 UsersRolesLoginModule 登录模块)。你需要这么设置:
<security:identity jaas-config-name="other"/>
需要记住的是,通过上面这些配置,并不是让用户验证交给了部署Seam应用程序的容器。它仅仅是告诉Seam安全框架使用在容器中配置的JAAS安全规则来验证用户。
15.3.1. 配置一个验证组件注意: 如果你使用Seam的身份管理功能(稍后介绍),那么就不用特地建立一个验证组件(意味着你可以跳过这一章)。
这种简单的验证方法由Seam的一个内置的JAAS登录组件提供,叫做SeamLoginModule,它将验证功能转移到你自己编写的一个Seam组件之中。该登录模块已经作为Seam的默认程序规则设置好了,你不需要额外的配置文件。你可以在一个编写一个你自己的方法来进行验证,稍经修改也可以用来结合其他第三方程序进行验证。这些简单的配置需要在components.xml中添加一个identity组件:
<components xmlns="http://jboss.com/products/seam/components" xmlns:core="http://jboss.com/products/seam/core" xmlns:security="http://jboss.com/products/seam/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.1.xsd http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.1.xsd "> <security:identity authenticate-method="#{authenticator.authenticate}"/>components>
EL表达式#{authenticator.authenticate}绑定到验证组件的验证方法上,该方法被用来对登录的用户进行验证。
15.3.2. 编写验证方法components.xml文档中identity的authenticate-method属性指出SeamLoginModule将使用哪个方法来进行用户验证。该方法没有参数,并且返回值为boolean类型,用于判断登录是否成功。用户名和密码可以分别从Credentials.getUsername()和Credentials.getPassword()得到。用户所属的角色通过Identity.addRole()来添加。下面就是一个写在POJO组件中的完整验证方法:
@Name("authenticator") public class Authenticator { @In EntityManager entityManager; @In Credentials credentials; @In Identity identity; public boolean authenticate() { try { User user = (User) entityManager.createQuery( "from User where username = :username and password = :password") .setParameter("username", credentials.getUsername()) .setParameter("password", credentials.getPassword()) .getSingleResult(); if (user.getRoles() != null) { for (UserRole mr : user.getRoles()) identity.addRole(mr.getName()); } return true; } catch (NoResultException ex) { return false; } } }
在上面的例子中,User和UserRole都是实体。 roles属性包含了用户所拥有的角色,这个属性必须是一个字符串组成的Set,例如“admin”、“user”等。上面的程序中,如果符合条件的用户记录没有找到,那么抛出NoResultException 异常,验证失败,登录失败。
提示:当编写验证方法的时候,必须保证这个方法为最简的,因为Seam安全无法保证这个方法会被调用多少次,同一个请求中它可能被调用多次。因此,任一判断成功或失败之外的代码,应该写成实现an event observer。想要知道Seam安全所提交事件的更多信息,请参考后面的安全事件一章。
15.3.2.1. Identity.addRole()Identity.addRole()方法会根据当前session是否有效来执行不同的任务。如果当前session未经过验证,那么addRole()只会在验证过程中被调用。该方法被调用的时候,角色名称会被加入pre-authenticated的临时角色列表。一旦验证成功,pre-authenticated中的临时角色会变为真正的角色,并且在调用Identity.hasRole()的时候,会返回true。The following sequence diagram represents the list of pre-authenticated roles as a first class object to show more clearly how it fits in to the authentication process.
如果当前session通过验证,然后调用Identity.addRole(),就会立即将指定的角色赋予当前用户。
15.3.2.2. 编写一个与安全事件相关的observer让我们来讨论一个实际例子。当登录成功以后,一些用户数据需要被更新。这个功能可以通过编写一个事件观察器的方式来实现,通过监听org.jboss.seam.security.loginSuccessful事件,像这样:
@In UserStats userStats;@Observer("org.jboss.seam.security.loginSuccessful")public void updateUserStats() { userStats.setLastLoginDate(new Date()); userStats.incrementLoginCount();}
这个观察器方法可以放在任何地方,甚至是验证组件里面。你可以在后面的章节中找到更多关于安全事件的内容。
15.3.3. 编写一个登录表单credentials组件里面提供了username与password属性,符合绝大多数常用的用户登录验证情况。这些属性可以直接被绑定到登录表单的相关输入区上。一旦对这些属性进行了相关设定,那么调用identity.login()就会使用credentials对用户进行权限验证。下面就是一个简单的登录表单例子:
<div> <h:outputLabel for="name" value="Username"/> <h:inputText id="name" value="#{credentials.username}"/>div><div> <h:outputLabel for="password" value="Password"/> <h:inputSecret id="password" value="#{credentials.password}"/>div><div> <h:commandButton value="Login" action="#{identity.login}"/>div>
和登录类似,退出登录可以调用#{identity.logout}。调用这个方法会清除当前登录用户的登录状态,并且让当前用户的session失效。
15.3.4. 配置概述总的来说,配置登录验证,只需要三个步骤:
1、在components.xml中设置登录验证方法
2、编写一个登录验证方法
3、编写一个登录表单让用户可以有地方登录
15.3.5. 记住我Seam安全框架提供了一个类似“记住我”的功能,这个功能我们经常能在其他网站上看见。这个功能实际上是提供了两种不同的习惯或者模式。
第一种模式,浏览器将用户名通过cookie的方式保存下来,只保留密码文本框让用户填写(市面上常见的浏览器都提供了保存密码的功能)。
第二种模式,在cookie中保留用户的唯一性认证信息,允许用户下次登录网站的时候不用输入密码就能够自动通过登录权限验证。
警告
使用客户端的cookie记录用户信息,从而实现自动登录的方式是非常危险的。虽然你方便了客户,但是同时,你站点上的任何一个跨站点脚本安全漏洞都可能会造成严重的后果。如果没有登录验证cookie,那么黑客唯一能够通过XSS偷取的信息就只剩下当前用户的session了。这就意味着,只有当用户登录网站创建了一个session的一小段时间才可能被攻击。如果黑客能够通过“记住我”这个功能从保存在客户端的cookie中得到用户的帐号信息,那么他以后随时都能够以客户的身份通过登录验证。当然,你需要知道,前面说的这些攻击能否实现,也取决于你对XSS攻击做了哪些防范。如果你能够确保你的网站100%防御了XSS攻击,你完全可以让用户输入的数据全部都显示在页面上。只要你能够实现,这绝对是意见了不起的成就。
现在,几乎所有浏览器厂商都认识到了这个问题,并且提供了一个“保存密码”的功能。浏览器会为网站的一些页面,或者是一个domain保存用户的用户名和密码。这样用户在登录网站的时候,即使session未经过登录验证,浏览器也会自动将用户名密码填入指定的登录表单。网站的设计者可以放一个登录快捷键在页面上,然后让浏览器去记录用户名和密码,这样实现类似“记住我”的功能会更加安全。一些浏览器(例如Safari和OS X)甚至能够将用户的登录数据加密并保存在操作系统的密码表中。如果是在网络环境下,这个密码表还可以跟随用户到任何地方(例如从用户的台式机到笔记本)。而cookie在通常情况下是无法实现同步的。
总结:你最好在任何情况下都不要使用cookie来实现自动登录验证。不过,仅仅使用cookie来记住用户名,并且自动将保存的用户名填写进入表单中,就不会有太大的问题,同时也能在一定程度上方便用户。
如果想要默认打开“记住我”的功能(仅仅记住用户名),你不需要做任何额外的配置。只需要在登录表单中将记住我的复选框绑定到rememberMe.enabled,就像下面这个例子里面写的:
<div> <h:outputLabel for="name" value="User name"/> <h:inputText id="name" value="#{credentials.username}"/>div><div> <h:outputLabel for="password" value="Password"/> <h:inputSecret id="password" value="#{credentials.password}" redisplay="true"/>div><div class="loginRow"> <h:outputLabel for="rememberMe" value="Remember me"/> <h:selectBooleanCheckbox id="rememberMe" value="#{rememberMe.enabled}"/>div>
15.3.5.1. 基于特征的记住我验证如果你需要使用记住我功能中基于特征的自动验证模式,你首先需要配置一个特征仓库。最常见的方式就是将验证特征存储在一个数据库中(Seam支持的数据库)。你也可以通过实现org.jboss.seam.security.TokenStore接口的方式实现特征仓库。本节假设你使用使用一个虚拟的JpaTokenStore实现将验证需要用到的所有特征数据存储在数据库的一个表中。
首先你需要创建一个新的包含了tokens的Entity。下面这个例子展现了一种你可能用到的结构:
@Entitypublic class AuthenticationToken implements Serializable { private Integer tokenId; private String username; private String value; @Id @GeneratedValue public Integer getTokenId() { return tokenId; } public void setTokenId(Integer tokenId) { this.tokenId = tokenId; } @TokenUsername public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @TokenValue public String getValue() { return value; } public void setValue(String value) { this.value = value; }}
在上面的例子中,我们使用了一对特殊的注解,@TokenUsername和@TokenValue,它们用来指出实体的username和特征属性。这些注解标识了实体中需要用来验证的所有特征数据。
下一步就是配置JpaTokenStore,使用entity bean来存储或读取验证特征。具体的操作为,在components.xml中加入一个token-class属性:
<security:jpa-token-store token-class="org.jboss.seam.example.seamspace.AuthenticationToken"/>
然后,在components.xml加入RememberMe设置,并且将模式设置为autoLogin:
<security:remember-me mode="autoLogin"/>
通过上面这些设置,用户每次访问你的网站的时候就可以自动登录了(只要用户点击了“记住我”复选框)。
15.3.6. 处理安全异常在登录的时候难免出现异常,为了防止用户看见默认的错误页面,我们建议你在pages.xml里面配置一下页面自动跳转设置,这样就能够在出错的时候自动跳转到一些比较“漂亮”的页面上。最常见的两种安全异常为:
NotLoggedInException:这个异常在用户没有登录就尝试访问需要登录才能访问的页面的时候出现。
AuthorizationException:这个异常只出现在这种情况,用户已经登录了,并且访问某个页面,但是他并没有访问这个页面的权限。
在出现NotLoggedInException异常的情况下,我们建议将页面跳转到登陆页面或者注册页面
在出现AuthorizationException异常的时候,可以跳转到一个提示用户没有相应权限的页面。
下面是一个pages.xml文件的片段,这里面配置了这两种安全异常出现时的跳转规则:
<pages> ... <exception class="org.jboss.seam.security.NotLoggedInException"> <redirect view-id="/login.xhtml"> <message>You must be logged in to perform this actionmessage> redirect> exception> <exception class="org.jboss.seam.security.AuthorizationException"> <end-conversation/> <redirect view-id="/security_error.xhtml"> <message>You do not have the necessary security privileges to perform this action.message> redirect> exception>pages>
大部分web应用程序会需要更多的跳转规则,用以处理各种实际业务逻辑。所以Seam包含了一些特殊的功能用来处理这些问题。
15.3.7. 登录重定向当用户在没有登录的情况下试图访问某个需要登录才可以访问的页面(或者是一组用通配符指定的页面)的时候,Seam会将用户转到一个登录页面:
<pages login-view-id="/login.xhtml"> <page view-id="/members/*" login-required="true"/> ...pages>
当用户登录了以后,我们需要自动跳转到用户刚才未登录时尝试访问的页面。通过在components.xml中进行一下配置,就可以实现。并且跳转回刚才的页面的时候,所有的请求参数都会被保留。
<event type="org.jboss.seam.security.notLoggedIn"> <action execute="#{redirect.captureCurrentView}"/>event><event type="org.jboss.seam.security.postAuthenticate"> <action execute="#{redirect.returnToCapturedView}"/>event>
需要注意一下,登录跳转功能是基于会话范围实现的,所以不要在authenticate()方法中结束当前会话。
15.3.8. HTTP验证Seam也提供了HTTP Basic或HTTP Digest (RFC 2617)方式的验证。不过除非必要,我们不建议使用这些方式。在components.xml文件中,我们需要进行以下配置:
<web:authentication-filter url-pattern="*.seam" auth-type="basic"/>
如果需要使用digest验证方式,key和realm也需要设置一下:
<web:authentication-filter url-pattern="*.seam" auth-type="digest" key="AA3JK34aSDlkj" realm="My App"/>
key属性可以是任意值。realm为用户在登录的时候需要告诉用户的realm名称。
15.3.8.1. 编写Digest验证器当使用digest验证方式的时候,你的验证类需要集成自抽象类org.jboss.seam.security.digest.DigestAuthenticator,并且使用validatePassword()方法来验证用户的纯文本密码。例如:
public boolean authenticate() { try { User user = (User) entityManager.createQuery( "from User where username = :username") .setParameter("username", identity.getUsername()) .getSingleResult(); return validatePassword(user.getPassword()); } catch (NoResultException ex) { return false; }}
15.3.9. 高级验证特性本节将探索一些安全API中提供的高级验证特性,用来满足各种复杂的验证需求。
15.3.9.1. 使用容器的JAAS配置如果你不需要使用Seam Security API提供的简化了的JAAS配置,那么你可以将其委托给系统默认的JAAS配置。你可以通过在components.xml配置一个jaas-config-name来实现。例如,如果你使用JBoss AS,并且希望使用其他的验证策略(例如使用JBoss AS提供的 UsersRolesLoginModule 登录模块)。你需要这么设置:
<security:identity jaas-config-name="other"/>
需要记住的是,通过上面这些配置,并不是让用户验证交给了部署Seam应用程序的容器。它仅仅是告诉Seam安全框架使用在容器中配置的JAAS安全规则来验证用户。
发表评论
-
JBoss Seam事件机制 (4):页面动作
2009-06-24 13:47 1676在JBoss Seam事件机制(1 ... -
JBoss Seam的事件机制 (3)
2009-06-24 13:46 1412JBoss Seam如何做到松耦合 ... -
JBoss Seam的事件机制 (2)
2009-06-24 13:45 1292JBoss Seam如何做到松耦合 ... -
JBoss Seam的事件机制 (1) 内置的上下文事件
2009-06-24 13:45 1655在JBoss Seam的事件机制(1)概述中我们提到Seam提 ... -
Seam 2.1中的安全升级 (二)
2009-06-24 13:43 1617Permission Management 尽管 Ident ... -
Seam 2.1中的安全升级 (一)
2009-06-24 13:41 1375Seam安全升级 by Shane Bryzak,翻译:JS ... -
seam2.1权限验证(15.5)@Restrict注解 (三)
2009-06-24 13:39 142715.6.8. 权限验证的模型 ... -
seam2.1权限验证(15.5)@Restrict注解 (二)
2009-06-24 13:37 159715.6.5. 实体安全控制(Securing Entitie ... -
seam2.1权限验证(15.5)@Restrict注解 (一)
2009-06-24 13:36 235115.5. 错误消息安全API内 ... -
seam2.1权限验证(15.4) jpa-identity-store
2009-06-24 13:34 206415.4. 身份管理身份管理功能提供了一组标准的API接口,用 ... -
seam发送邮件email示例
2009-06-24 13:33 1601以下转自csdn上的一个回答,留着用的时候参考,防止到时找不到 ... -
扩展seam组件
2009-06-24 13:31 1101任何一个框架都必须拥有一个非常重要的功能:可扩展性。JBoss ... -
Seam Bean验证快速进阶II:自定义约束
2009-06-24 13:26 1400本文为Bean验证系列的第二部分。总体介绍请阅读这篇文章。本文 ...
相关推荐
相较于 Seam 2.0 版本,Seam 2.1 在权限验证方面进行了大量的增强,引入了更多的功能和改进,以适应更加复杂的应用场景。 #### 二、Seam 2.1 的新增特性与改进 在 Seam 2.1 中,最显著的变化之一就是增强了安全性...
### Seam 2.1 参考手册核心知识点详解 #### 一、Seam 2.1 GA 版本概述 Seam 2.1 GA版本是Seam框架的一个重要更新,该版本带来了许多新的特性和改进,使得Seam更加适合于现代的企业级应用开发。 #### 二、支持...
3. **权限验证**:Seam 包含一个广泛适用的权限验证框架,支持基于角色的访问控制(RBAC)、持久化权限设置以及规则驱动的权限决策。这使得开发者可以根据业务逻辑创建自定义的安全策略。 4. **权限管理**:Seam ...
### 基于Seam2.1的最新力作《Seam Framework: Experience the Evolution of Java EE, 2nd Edition》全书知识点概览 #### 一、Seam框架简介 Seam框架是JBoss组织推出的一个开源项目,旨在简化企业级应用开发,通过...
Seam 是一种业级 企 Java 的应规用程序框架。它的灵感源自下列原 : 只有一种“工具” Seam为 应 业务业业 义 种统 组 你的 用程序中所有的 定 了一 一的 件模型。 Seam组件可能是 态义 关关 态 有状 的,包含与几...
### JBoss Seam 2.1版本开发参考知识点 #### 一、JBoss Seam 框架简介 **JBoss Seam** 是一个企业级Java Web应用框架,它简化了基于Java平台的应用程序开发过程。该框架提供了强大的上下文管理功能、会话管理、...
- **实现**:通过集成Spring Security等第三方库来实现权限验证和访问控制等功能。 - **优势**:易于集成和配置,能够快速为应用程序添加安全特性。 ##### Application Framework - **概述**:Seam框架不仅限于Web...
在本篇讨论中,我们将深入探讨如何在Seam框架下进行基于数据库的权限验证,以此来确保用户只有在具备相应权限的情况下才能访问特定的资源。 首先,我们要理解Seam中的安全模型。Seam使用了JSF(JavaServer Faces)...
整理自jboss seam 中文站,压缩为chm格式,便于广大jboss seam爱好者阅读,所有版权归jboss seam中文站所有。
- **运行测试**:这部分可能涉及了如何使用单元测试或者集成测试来验证应用程序的功能。 ##### 1.2 第一个例子:注册示例 这个例子展示了如何使用 Seam 构建一个用户注册系统。 - **了解代码**:这部分详细解释了...
Seam Security是针对Java Web应用程序的安全框架,它是JBoss Seam项目的一部分,提供了全面的安全解决方案,包括身份验证、授权和身份管理等功能。Seam Security以易于配置和使用为特点,允许开发者快速设置应用程序...
5. **安全和身份验证(Security and Authentication)**: Seam集成了JAAS(Java Authentication and Authorization Service),提供了用户认证和权限管理功能。 **三、Seam与Java EE集成** 1. **JSF集成**: Seam与...
在安全方面,Seam支持身份验证和授权,可以轻松地集成到已有的安全框架,如JAAS(Java Authentication and Authorization Service)。它还提供了对富客户端应用的支持,比如AJAX功能,这使得Web应用能够实现更丰富的...
Seam支持拦截器机制,可以用来增强组件的行为,例如日志记录、权限检查等。 **3.2.7 组件名字** 每个Seam组件都有一个唯一的名称,用于在应用中引用该组件。 **3.2.8 定义组件范围(Defining the Component Scope...
4. **安全与身份验证**:了解Seam的安全特性,如身份验证、授权和会话管理。 5. **持久化与数据访问**:研究Seam如何通过JPA进行数据存储和检索,以及Seam的缓存和查询优化功能。 6. **国际化与本地化**:学习如何在...
#### 2.1 第一部分:起步使用Seam - **第1章:Seam统一Java EE 3**:介绍 Seam 如何整合 Java EE 3 技术,形成统一的应用开发平台。 - **第2章:将Seam-Gentoo投入工作**:展示如何在 Gentoo Linux 系统上安装和配置...
2.1 JSF(JavaServer Faces)集成 Seam 2.0与JSF紧密集成,提供了组件扩展和增强,如Seam Faces,增强了JSF的表单处理和导航能力。 2.2 EJB(Enterprise JavaBeans)支持 Seam 2.0通过其EJB容器,让开发者可以方便...
### JBoss Seam 教程知识点概述 #### 一、Seam简介与教程概览 - **Seam**:一个基于Java EE平台的应用框架,旨在简化企业级应用开发。 - **JBoss Seam**:由JBoss提供的Seam实现,提供了一系列功能强大的工具和...
Seam Security 中的验证特性是基于JAAS (Java Authentication and Authorization Service)开发的,它提供了用来进行用户身份认证的高度可配置的接口。然而,针对复杂多变的验证需求,Seam Security 提供了一套非常...