我很高兴宣布 Seam Security 3.0.0 Alpha1 的可用性。这个版本是对 Seam 2.x 中的安全特性的重大重构,因此我提前为长篇的发布说明道歉。首先,重要的内容
分发下载
Maven 依赖项
<dependency> <groupId>org.jboss.seam.security</groupId> <artifactId>seam-security-impl</artifactId> <version>3.0.0.Alpha1</version> </dependency>
或者,您可以在编译时使用 API,并在运行时仅包含实现。
<dependency> <groupId>org.jboss.seam.security</groupId> <artifactId>seam-security-api</artifactId> <version>3.0.0.Alpha1</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.jboss.seam.security</groupId> <artifactId>seam-security-impl</artifactId> <version>3.0.0.Alpha1</version> <scope>runtime</scope> </dependency>
注意:您必须在您的settings.xml或项目 POM 中配置
JIRA
http://jira.jboss.org/jira/browse/SEAMSECURITY
我需要强调这是一个 alpha 版本,因此一些功能可能缺失或不完整,肯定会有一些错误。我希望邀请每个人充分利用 JIRA 报告任何发现不正常或缺失的内容,这将极大地帮助我们为后续版本做准备。
言归正传,现在是时候系好安全带,看看有哪些变化。
API 和实现分离
和许多其他 Seam 3 模块一样,我们将安全模块分为 API 和 IMPL 子模块。这是 Seam Security 请求已久的特性,允许在单元测试等中使用替代实现。核心组件,如 Identity、Credentials 等,现在基于接口。
基本认证
通过类似于 Seam 2 的简单认证方法进行认证在原则上相当相似。您不需要在components.xml(现在已经不存在了)中配置认证器方法,您只需在您的应用程序中提供org.jboss.seam.security.Authenticator接口的实现即可。当调用Identity.login()时,安全模块将搜索实现Authenticator接口的 bean,如果找到则使用它进行认证。此接口声明了一个单一的方法,authenticate():
public interface Authenticator { boolean authenticate(); }
实现可能执行必要的任何逻辑以验证用户身份,无论是查询数据库还是从文件中读取用户账户信息。凭据(包含用户的用户名和密码)可以通过直接注入org.jboss.seam.security.Credentialsbean 来获取。Authenticator.
public class SimpleAuthenticator { @Inject Credentials credentials; public boolean authenticate() { // authentication logic here return true; // if authentication successful } }
PicketLink
Seam Security 中的一个主要变化是集成 PicketLink。在 Seam 3 的规划阶段初期,我们决定研究如何将我们的安全努力与 JBoss 安全团队合作统一。Seam 已经有了身份管理功能,然而与具有相似目标的 PicketLink IDM 项目并行(因此竞争)开发这些功能是没有意义的。因此,我们决定从 Seam 中删除身份管理功能,并采用 PicketLink IDM 作为我们的身份管理提供商。
PicketLink 提供了使用 Hibernate 或 LDAP 存储与身份相关的信息的实现,但缺乏 JPA 实现。Seam 3 通过提供名为JpaIdentityStore的 JPA 实现来弥合这一差距,该实现受到了 Seam 2 中实现的启发。这是一个全新的编写,在将遗留数据库模式(其中包含与身份相关的数据)集成到配置中提供了更多的配置灵活性。这个身份存储实现 可能 最终会进入 PicketLink 项目的代码库。JpaIdentityStore要使用
为您的项目提供身份管理功能,您需要在其JpaIdentityStore配置文件中配置它beans.xml(或seam-beans.xml)文件(需要 Seam-XML 模块)。首先,您需要在根元素内配置一个命名空间
xmlns:plidm="urn:java:org.jboss.seam.security.management.picketlink"
然后,您需要配置包含用户账户、凭据、角色和关系等内容的实体类
<plidm:JpaIdentityStoreConfiguration> <s:replaces/> <plidm:identityClass>org.jboss.seam.security.examples.idmconsole.model.IdentityObject</plidm:identityClass> <plidm:credentialClass>org.jboss.seam.security.examples.idmconsole.model.IdentityObjectCredential</plidm:credentialClass> <plidm:relationshipClass>org.jboss.seam.security.examples.idmconsole.model.IdentityObjectRelationship</plidm:relationshipClass> <plidm:roleTypeClass>org.jboss.seam.security.examples.idmconsole.model.IdentityRoleName</plidm:roleTypeClass> </plidm:JpaIdentityStoreConfiguration>
上面的示例来自包含在 Seam Security 分发中的 idmconsole 示例应用程序。这是一个简单但简洁的示例,演示了您如何构建一个用于管理您应用程序中的用户、角色和组的界面。
另一个需要注意的重要变化是,IdentityManager组件不再是 Seam 3 的一部分。取而代之的是,一组操作 bean,位于org.jboss.seam.security.management.action包中。这些 bean 旨在直接由视图层(如 JSF)使用,以简化应用程序与 PicketLink IDM 管理 API 之间的交互。如果您想要直接访问 API,您可以直接将org.picketlink.idm.api.IdentitySession注入到您的 bean 中
@Inject IdentitySession identitySession;
从IdentitySession,您可以访问PersistenceManager, RelationshipManager, RoleManager等,以对身份管理 API 的所有方面进行细粒度控制。有关更多信息,您可以参考此处 PicketLink 文档
API 变更,JAAS 废弃
随着转向 PicketLink,我们还采用了他们的 Identity API,利用基于 PicketLink 的基本类 User、Role 和 Group。因此,我们不再在Identitybean 中使用 JAAS API,原始的认证机制(也是基于 JAAS)也已删除。这给了我们支持 Group(在 Seam 2.x 中,group 的概念是允许角色的分组)的优势。在 Seam 3 中,角色现在是用户与组之间的类型映射。例如,“bob”(一个用户)可能是“head office”(一个组)中的“manager”(角色类型)。这为我们提供了对用户组权限的更细粒度控制。
基于规则的权限
Seam 3 中基于规则的权限发生了一些细微的变化。首先,不再需要配置规则文件,只要它命名为security.drl并且根据焊接扩展资源加载器的标准位置之一进行定位。其次,现在它不是断言从Principal获取的Identitybean到工作内存中,而是断言一个User对象,并将分配给当前用户的每个Role和Group成员资格注入。因此,您需要修改安全规则文件的导入,以下是一个示例
import org.jboss.seam.security.permission.PermissionCheck; import org.picketlink.idm.api.Role; import org.picketlink.idm.api.Group;
在规则中执行的Role检查略有不同。以下是从idmconsole演示的示例
rule CreateAccount no-loop activation-group "permissions" when check: PermissionCheck(resource == "seam.account", permission == "create", granted == false) Role(roleType.name == "admin") then check.grant(); end
程序化授权
我们从Seam 3中移除了@Restrict注解,因为这个基于EL的安全机制没有提供CDI编程模型所鼓励的那种类型安全性。目前我们还没有一个类型安全的基于注解的替代品,但我们可能会在最终发布之前引入一个。现在,可以通过将Identity bean注入到您的应用程序bean中来以程序方式执行授权
@Inject Identity identity;
然后可以像这样执行Role检查
identity.checkRole("superuser", "Head Office", "GROUP");
如果用户没有所需的Role,将抛出AuthorizationException。简单的组成员资格检查也可以以类似的方式进行
identity.checkGroup("Head Office", "GROUP");
权限检查与Seam 2.x中的权限检查非常相似,只是术语略有变化。为了与PicketLink保持一致,我们将target
重命名为resource
,将action
重命名为permission
。检查用户权限的API现在看起来像这样
void checkPermission(Object resource, String permission);
再次,资源参数用于指定您要测试当前用户是否有权与之交互的对象,而权限参数是用户希望在资源上执行的具体操作名称。例如,假设我们有一个Account对象,当前用户希望删除它。为了检查他们是否有执行此操作的必要权限,我们执行权限检查,如下所示
identity.checkPermission(account, "delete");
那么接下来是什么?
以下是一份清单,列出了没有完全包含在alpha版本中,但在最终版本中计划实现的功能
- 外部认证模块(预计将在Alpha2中推出)
- 持久权限(即ACLs)
- 记住我
- 单元测试
- 文档
- 更多示例