【发布时间】:2022-01-20 11:42:29
【问题描述】:
在 Wildfly (Jboss) 中运行的当前应用程序使用其自己的身份验证系统,该系统在内部验证其数据库上的密码和凭据。
随着我们迁移到微服务模式,该系统在未来不再可行,因此最初需要使用 OpenId Connect 协议进行身份验证的分布式登录系统,稍后会进行授权。
这已通过使用 Spring 安全性和 Spring OAuth2 客户端的新 Spring Boot 微服务很好地实现,但是将这些库与旧的 Jakarta EE 应用程序集成是一个挑战。
实施
- 春季版 - 5.3.13
- Spring Security 版本 - 5.5.3
- Omnifaces 版本 - 3.11.2
- Jakarta EE 版本 - 8
- Wildfly 应用程序容器 - 23
- 现有的身份验证系统使用 Java EE HttpAuthenticationMechanism 和 AuthenticatedUser bean,其作用类似于主体。
- 我在 Java EE 应用程序中添加了 Spring 安全性和 OAuth2 客户端。它工作正常,将人们重定向到 AWS Cognito SSO 页面,并在他们登录后使用授权代码重定向回来。
这是一个总结了当前一起被黑的图表
测试
我创建了两个带有支持 bean 的基本 JSF 页面,一个使用 web.xml 中定义的旧 Javax 安全规则进行保护,另一个使用 Spring 安全配置 bean 定义。
使用 Spring 安全页面,我可以在 bean 中获取 Security 上下文(我认为这使用 ThreadLocal)
例如 Helloworld 支持 Bean
@Named
@ViewScoped
public class HelloWorldBacking implements Serializable
{
private static final long serialVersionUID = 1L;
public String getAuthDetails() {
SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
return authentication.getName();
}
}
Spring 安全配置
@Configuration
@EnableWebSecurity
@PropertySource("classpath:application.properties")
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final String clientSecret;
private final String clientId;
private final String issuerUri;
@Autowired
public SecurityConfiguration(@Value("${oauth.issuer-uri}") String issuerUri,
@Value("${oauth.client-id}") String clientId,
@Value("${oauth.client-secret}") String clientSecret) {
this.issuerUri = issuerUri;
this.clientId = clientId;
this.clientSecret = clientSecret;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
.and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.cors()
.and()
.authorizeRequests()
.antMatchers("/helloworld-spring").hasAuthority("Admin")
.and()
.oauth2Login()
.and()
.oauth2ResourceServer()
.jwt();
}
...
但是,如果我不使用 Spring 安全性保护该 JSF 页面,我将无法获得任何上下文。
问题
当 JSF 页面已使用旧的安全方式进行保护时,它似乎走上了一条不同的道路,其上下文都由 CDI 管理。
我想将 Spring 安全主体集成到 JSF 应用程序的所有部分。以便 JSF 在其上下文中了解它。
调试
在调试某些现有页面时,似乎两个 Auth 系统都已激活,但存在分歧且彼此不了解。
解决方案?
作为一个被spring boot auto配置的奢华宠坏的人,我有点卡住了。
只需覆盖一个类,这可能是一个简单的解决方法,或者:
- 我是否需要淘汰使用 Java EE 规范的旧身份验证系统?
- 是否要覆盖 Spring 安全性的某些部分以使其能够识别 Java EE 和 JSF?
- 是否需要将 JSF 配置为与 Spring 安全性通信?
- Wildfly 应用服务器中是否有更高级别的抽象需要配置?
tl;dr
如何在 Jakarta EE 应用程序中让 Spring security 将其安全上下文传递给 JSF?
谢谢
【问题讨论】:
-
请看题前言;因为 Java EE 已经过时,不够灵活,我们需要在单体应用程序之外提取身份验证。
-
“因为 Java EE 已经过时了” 1:一点也没有。 2:为什么会有人想混合使用spring和javaEE?
-
“我们需要在单一应用程序之外提取身份验证” - 您可以使用 Java EE 安全性完美地做到这一点。您可以在应用程序内部安装一个通过远程服务器进行身份验证的身份验证机制,或者您甚至可以在应用程序外部拥有该身份验证机制和/或身份存储。
标签: java jsf jakarta-ee spring-security jakarta-ee-security-api