1

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

随着我们迁移到微服务模式,该系统在未来不再可行,因此最初需要使用 OpenId Connect 协议进行身份验证的分布式登录系统,稍后将进行授权。

使用 Spring security 和 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();
    }
}

春季安全配置

@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 系统都已激活,但存在分歧并且彼此不了解。

解决方案?

作为一个被弹簧靴自动配置的奢华宠坏的人,我有点不知道该怎么做。

只需覆盖一个类,或者:

  • 我是否需要淘汰使用 Java EE 规范的旧身份验证系统?
  • 我是否覆盖了 Spring 安全性的某些部分,以便它知道 Java EE 和 JSF?
  • 是否需要将 JSF 配置为与 Spring 安全性通信?
  • Wildfly 应用程序服务器中是否有更高级别的抽象需要配置?

tl;博士

在 Jakarta EE 应用程序中,如何让 Spring 安全将其安全上下文传递给 JSF?

谢谢

4

1 回答 1

1

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

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

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

ps

OpenId Connect 目前包含在现在称为 Jakarta EE 安全性中,请参阅https://github.com/jakartaee/security/pull/185

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

于 2021-12-17T15:42:37.413 回答