【问题标题】:Integrating Spring Security with Jakarta EE 8 Security and JSF?将 Spring Security 与 Jakarta EE 8 Security 和 JSF 集成?
【发布时间】: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
  1. 现有的身份验证系统使用 Java EE HttpAuthenticationMechanism 和 AuthenticatedUser bean,其作用类似于主体。
  2. 我在 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


【解决方案1】:

在 Wildfly (Jboss) 中运行的当前应用程序使用其自己的身份验证系统,该系统在内部验证其数据库上的密码和凭据。

从您的图中,它看起来不是“自己的身份验证系统”,而是使用 Java EE 安全性。没有必要用任何 Spring 替换它。

完成这项工作的最佳方法是保持原样。 Java EE Security 是专门为与 JSF 一起工作而设计的,两者很好地集成在一起。在这里混合使用您自己的安全系统可能会在以后提出问题。

附言

OpenId Connect 目前包含在现在称为 Jakarta EE Security 的内容中,请参阅 https://github.com/jakartaee/security/pull/185

WildFly 上的 Java EE 安全性与 MicroProfile API 配合得非常好,其中包括 JWT 身份验证机制。参见示例

【讨论】:

  • 谢谢,PR 没有合并。是否有任何其他“具体”替代方案可以将 OAuth2 集成到 Java EE?
  • @tomaytotomato 是的,Payara 提供了一个具体的地址:github.com/payara/ecosystem-security-connectors/tree/master/… 和 maven 坐标 fish.payara.security.connectors:security-connector-oauth2-client
  • 我在一年前也做过,但是我已经很久没有尝试过这个了(我的项目现在都使用 JWT),但如果它仍然有用:github.com/omnifaces/soteria-google-oauth-client
  • 我尝试使用安全连接器 Oauth2 Open ID 客户端,但它抛出此错误:Error getting ServerAuthContext for authContextId default-host and security domain jaspitest: javax.security.auth.message.AuthException Wildfly23 是否需要来自 Payara 框架的特殊依赖项/配置?我只有一个带有“jaspitest”的基本安全领域
  • 总的来说,WildFly 很不幸地违反了 Jakarta 安全规范,需要特殊设置。但是,如果您当前的设置已经使用 Jakarta Security,那么这个设置应该已经设置好了。见stackoverflow.com/questions/70225352/…
猜你喜欢
  • 2013-09-23
  • 2012-11-14
  • 2012-08-12
  • 2015-06-29
  • 1970-01-01
  • 1970-01-01
  • 2016-03-11
  • 2014-05-22
  • 2011-12-26
相关资源
最近更新 更多