领先一步
VMware 提供培训和认证,助您快速提升。
了解更多我非常高兴地代表 Spring 和 Apache Geode 社区宣布,面向 Apache Geode 1.0.0-incubating 的 Spring Data 已发布。
您可以通过在应用的 Maven POM 或 Gradle 构建文件中包含以下依赖项来从 Maven Central 获取相关文件...
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-geode</artifactId>
<version>1.0.0.INCUBATING-RELEASE</version>
</dependency>
compile 'org.springframework.data:spring-data-geode:1.0.0.INCUBATING-RELEASE'
包含 spring-data-geode
依赖项将传递地引入所有必需的 Apache Geode 工件,因此您现在可以开始构建使用 Apache Geode 的 Spring 应用了。
我再次更改了版本限定符,移除了
APACHE-GEODE
限定,并简化为INCUBATING-RELEASE
。一旦 Apache Geode 从孵化器毕业,INCUBATING
限定也将取消,版本号将简单地变成major.minor.maint.[M#|RC#|RELEASE]
。
Spring Data Geode 1.0.0.INCUBATING-RELEASE 和 Apache Geode 1.0.0-incubating 的发布都意义重大,原因如下:
首先,也是最重要的是,这标志着 Apache Geode 在 Apache Software Foundation (ASF) 内的第一个 官方 GA 版本发布。这不仅标志着 Geode 的成熟(其根基在于十多年的生产经验,即 Pivotal GemFire),也加速了其在 ASF 内毕业成为顶级项目 (TLP) 的进程。
但这还不是全部!
此版本还通过引入一个新的集成安全框架(一些技术细节可在此处查看)对 Apache Geode 的安全模型进行了重大更改,该框架不仅包括安全传输(即 SSL),还包括身份验证和授权。
这一点意义重大,因为 Apache Geode 是少数提供安全功能而无需企业许可证的开源 IMDG 选项之一!
这项新功能最出色的方面之一是它是一个框架,允许插入不同的安全提供者。开箱即用,Geode 构建在 Apache Shiro 之上,它为 Geode 和您的应用提供了熟悉且强大的安全配置方式。
如果不使用 Spring (Data Geode),Apache Geode 提供自己的安全配置选项。
一种选择是实现 Apache Geode 的 SecurityManager 接口,并将其完全限定类名设置到相应的 Geode security-manager
(系统)属性中。示例可在此处查看。
但是,使用属性引用 FQCN 严重限制了您在托管环境或测试上下文中配置 SecurityManager
的方式。根据我的反馈,这将在稍后的 Geode 版本中得到解决。
另一种选择是使用 Apache Geode 的 security-shiro-init
(系统)属性来指定位于 Apache Shiro 支持的指定资源路径中的 INI 配置文件。然而,这有两个限制。
首先,目前 Apache Geode 仅支持 classpath:
资源指定符(Geode 工程团队也正在解决此问题)。其次,IMO,学习另一种配置文件格式,无论它多么标准,都不比 XML 好多少。
当然,Apache Shiro 试图通过提供此功能来减轻在 Spring 上下文中运行时遇到的麻烦。但是,仍然有太多样板配置逻辑需要改进。
为了使 Apache Geode 尽可能地快速且易于使用(请参阅我的上一篇博客文章),我一直与 Geode 工程团队紧密合作,改进初始设计,并通过采用 Spring Framework 和 Spring Boot 推广的许多基础 API 和框架设计概念,真正将集成安全在 Spring Data Geode 中打造成为一级公民。
因此,我向您介绍了 SDG 新的基于注解的配置模型中的新 @EnableSecurity
注解。您可以使用该注解以多种方式配置 Apache Geode 的安全功能。
您仍然可以通过其完全限定类名引用 Geode SecurityManager
实现,使用...
package example;
class ExampleSecurityManager
implements org.apache.geode.security.SecurityManager {
...
}
@CacheServerApplication(name = "ClassNameExample")
@EnableSecurity(securityManagerClassName = "example.ExampleSecurityManager")
class ExampleApplication {
...
}
更详细的示例可以在 SDG Contacts Application RI 中此处看到。
但是,您必须提供一个默认的无参构造函数,并且您的 Geode SecurityManager
实现将负责在构建时加载所有安全身份验证/授权详细信息;这不是很理想。
另一种选择是创建一个实现 Geode SecurityManager
接口的 Proxy
,它将委托给一个实际的、底层 Geode SecurityManager
,该 SecurityManager
在 Spring 容器或其他托管环境(如 Pivotal CloudFoundry)中配置并由其注入。
一个这样的 Proxy
实现在 RI 中可以此处看到,配置如下...
@CacheServerApplication(name = "ProxyExample")
@EnableSecurity(securityManagerClassName =
"example.app.geode.security.SecurityManagerProxy",
useBeanFactoryLocator = true)
class ExampleApplication {
...
@Bean
JdbcSecurityRepository securityRepository(JdbcTemplate template) {
return new JdbcSecurityRepository(template);
}
@Bean
SimpleSecurityManager securityManager(
SecurityRepository<User> securityRepository) {
return new SimpleSecurityManager(securityRepository);
}
}
SecurityMangerProxy
在缓存初始化期间由 Apache Geode 构建。Spring 容器将找到 SimpleSecurityManager Bean 定义,并将其注入到 SecurityManagerProxy
中。
SecurityManagerProxy
利用了 Spring 的另一个特性,即 BeanFactoryLocator,如参考指南(和此处)所述,SDG 使用它来配置和自动装配在 Spring 容器外部构建和初始化的对象,例如由 Apache Geode 构建和初始化的对象。
这在某些情况下很有用,例如应用程序对象(如 CacheLoader)可能在 Geode 的原生 cache.xml
配置中定义,并且需要与 Spring 容器中定义的 Bean(如 DataSource
)自动装配。这对于在 Geode (系统) 属性中引用的对象(如 SecurityManager
)也适用。
SecurityManagerProxy
必须继承 LazyWiringDeclarableSupport 类,这使得一旦 Geode 构建了该对象,Spring 容器就可以使用 BeanFactoryLocator
自动装配 Proxy
。这实际上非常巧妙。
您可以在 RI 此处看到完整的示例配置。这还需要在 Geode Server 的 Spring Boot 应用程序类上将 useBeanFactoryLocator
属性设置为 true,这在上面的示例中也有展示。
也许您不想让应用程序代码不必要地与 Geode 的专有类和接口(例如 SecurityManager
)耦合。也许您只是想充分利用 Apache Shiro 的安全框架。
一种方法是创建一个 Apache Shiro INI 配置文件,并在 @EnableSecurity
注解中引用它,如下所示...
@CacheServerApplication(name = "ProxyExample")
@EnableSecurity(shiroIniResourcePath = "my-shiro.ini")
class ExampleApplication {
...
}
同样,Apache Shiro INI 文件必须在类路径上。由于目前 Apache Geode 的限制,无法使用其他资源指定符(例如 file:
或 url:
)。
这个完整的示例配置可以在此处看到。
然而,作为应用程序开发人员,您真正想做的是仅在 Spring 容器中将 Apache Shiro Realms
定义为 Spring Bean,以便访问应用程序保护 Apache Geode 所需的安全元数据,然后让 Spring 完成所有工作。
嗯,SDG 也可以为您做到这一点。例如...
@CacheServerApplication(name = "RealmExample")
@EnableSecurity
class ExampleApplication {
@Bean
PropertiesRealm shiroRealm() {
PropertiesRealm propertiesRealm = new PropertiesRealm();
propertiesRealm.setResourcePath("classpath:shiro.properties");
propertiesRealm.setPermissionResolver(new GeodePermissionResolver());
return propertiesRealm;
}
}
就是这样;这就是您所需要的全部。
注意 Shiro 的 PropertiesRealm 使用 GeodePermissionResolver
来解析 Geode 权限。此外,您可以选择指定任何资源路径;您不受限于只能使用 classpath:
。
您还可以自由定义应用程序用于访问其安全元数据的 Shiro 提供的任何 Realms
(例如 JDBC、JNDI、LDAP 等)。
如果您定义了多个 Shiro Realm
,您甚至可以使用 Spring 的 @Order
注解在 Realm
Bean 定义上对它们进行排序,如下所示...
@CacheServerApplication(name = "OrderedMultiRealmExample")
@EnableSecurity
class ExampleApplication {
@Bean
@Order(1)
IniRealm iniRealm() {
IniRealm iniRealm = new IniRealm("classpath:partial-shiro.ini");
iniRealm.setPermissionResolver(new GeodePermissionResolver());
return iniRealm;
}
@Bean
@Order(2)
PropertiesRealm propertiesRealm() {
PropertiesRealm propertiesRealm = new PropertiesRealm();
propertiesRealm.setResourcePath("classpath:partial-shiro.properties");
propertiesRealm.setPermissionResolver(new GeodePermissionResolver());
return propertiesRealm;
}
}
Realm
排序是 Apache Shiro 身份验证序列中使用的身份验证策略中的一个重要因素。
您可以在 RI 此处看到使用 Shiro Realms
的多个示例配置。
我们已经讲了很多内容,但仍有很多工作要做。具体来说,我打算做以下工作...
还有更多工作正在进行中,敬请关注。
更多详细信息请参阅变更日志。
一如既往,欢迎您的反馈,您可以通过 JIRA 或 StackOverflow 与我们联系。
感谢大家!编码愉快。