JBoss Seam (POJO without EJB) 后台 + ExtJS 前台完整例子(十一)
1.引言
随着internet的发展,业务过程、事务以及企业信息需要向更广泛的用户群公开。这一变化给应用程序和基础设施带来了重大的影响,其中最明显的影响就是应用程序安全方面。Seam框架提供了可选的安全性API,可以实现身份验证(authentication)和授权(authorization)功能。
本文主要介绍项目中安全性方面的初步实践,更深入的内容有待于进一步的开发经验的积累。
2.基本的安全性需求
本项目要求实现下列基本的安全性需求:
(1)可以让用户没有限制地使用登录页面和注册新用户页面。
(2)其它任何页面,必须先登录才能使用。
(3)远程外观类中通过Seam Remoting暴露的后台服务,除登录和新建用户外,只能被已经登录的用户调用。
(4)通过Servlet暴露的服务,只能被已经登录的用户调用。
3. 扩展 Identity 类
Seam框架内建了Identity组件类,提供安全性管理功能。本项目通过 com.divo.core.misc.ExtendedIdentity 扩展了Identity 类:
java 代码
- @Name("org.jboss.seam.security.identity")
- @Scope(SESSION)
- @Install(precedence = APPLICATION)
- @BypassInterceptors
- @Startup
- public class ExtendedIdentity extends Identity {
- @Override
- public boolean hasPermission(String name, String action, Object... arg) {
- return true;
- }
- @Override
- public void checkPermission(String name, String action, Object... arg) {
- if (!isLoggedIn()) {
- Events.instance().raiseEvent("org.jboss.seam.notLoggedIn");
- throw new NotLoggedInException();
- }
- }
- @Override
- public void checkRestriction(String expr) {
- if (!isLoggedIn()) {
- Events.instance().raiseEvent("org.jboss.seam.notLoggedIn");
- throw new NotLoggedInException();
- }
- }
- }
如 这篇文章所述,通过无依赖扩展,ExtendedIdentity 将代替内建的 Identity 组件。
4. 页面访问权限控制
页面访问权限控制在 page.xml 中设置:
xml 代码
- <exception class="org.jboss.seam.security.NotLoggedInException">
- <redirect view-id="/app/home.xhtml">
- redirect>
- exception>
- <page view-id="/app/sample/*">
- <restrict/>
- page>
其中的 exception 配置,使得异常 NotLoggedInException 抛出时,会自动跳转到登录首页。而 page 属性配置,使得用户没有登录而试图访问 /app/sample 目录(及其子目录)下的页面时,将受到限制。
显然,用户访问 /app/sample 目录以外的页面时,将不受限制。
所谓“受到限制”,实际上就是Seam框架会自动调用 ExtendedIdentity 组件的 checkRestriction 方法。如果判断用户没有登录,则抛出 NotLoggedInException 异常。
5. 登录功能与Seam集成
应用程序通过用户名和密码让合法用户登录,为了利用Seam框架提供的安全性设施,需要与Seam集成。
本项目的集成方法如下:
第1步:配置 components.xml
xml 代码
- <security:identity authenticate-method="#{userService.authenticate}"/>
第2步:在 UserService 类中,按通常方法实现 login 服务。
第3步:登录验证通过后,在 Identity 组件中填入当前登录用户的用户名和密码,并调用其 login 方法:
java 代码
- identity.setUsername(name);
- identity.setPassword(password);
- identity.login();
第4步:按照 components.xml 中的配置,在 UserService 类在实现 authenticate 方法。
java 代码
- public boolean authenticate() {
- return true;
- }
因为应用程序的登录验证已经在 login 方法中实现,所以 authenticate 方法仅仅是走走形式而已。
第5步:在 UserService 类中实现注销功能:
java 代码
- identity.logout();
6. 使用@Restrict元注解
@Restrict 元注解可以应用到类,也可以应用到类方法。@Restrict 元注解将引导 Seam 框架去执行
Identity.checkRestriction() 方法。
本项目中,要求在服务层组件添加 @Restrict 元注解。因为远程外观类和Servlet类都必须通过服务层
组件实现具体的功能,因此同时满足了通过Seam Remoting和Servlet暴露的后台服务对安全性的要求。
7. 进一步的扩展
本项目实现的安全性还是初步的,实际项目往往会考虑按角色对用户进行分组。每个角色规定相应的权限。
通过进一步扩展 ExtendedIdentity.checkRestriction() 的功能,可以实现基于角色的安全性控制。
8. 结语
Seam框架提供的安全性API和机制细致而周到,简化了开发,值得进行深入的学习和研究。
附:下面是本系列所有文章的完整列表:
(1) 下载示例项目并安装运行
(2) 建立Eclipse开发环境
(3) 熟悉项目中与JSF相关内容
(4) 重新认识JS
(5) ExtJS之表单(Form)
(6) ExtJS之布局(Layout)
(7) ExtJS之网格(Grid)
(8) Java后台和前台的通讯机制
(9) Seam框架简化Java开发
(10) 分层架构设计
(11) 安全性
(12) 单元测试