简体   繁体   English

将 Spring 安全与 Jakarta EE 8 安全和 JSF 集成?

[英]Integrating Spring Security with Jakarta EE 8 Security and JSF?

A current application running in Wildfly (Jboss) uses its own Authentication system that internally verifies passwords and credentials on its Database.在 Wildfly (Jboss) 中运行的当前应用程序使用其自己的身份验证系统,该系统在内部验证其数据库上的密码和凭据。

This system is no longer viable for the future as we migrate to a microservices pattern, therefore requiring a distributed login system using OpenId Connect protocol for Authentication initially, authorization will come later.随着我们迁移到微服务模式,该系统在未来不再可行,因此最初需要使用 OpenId Connect 协议进行身份验证的分布式登录系统,稍后将进行授权。

This has been implemented fine with a new Spring boot microservice using Spring security and Spring OAuth2 client, however integrating those libraries with the old Jakarta EE application is proving a challenge.使用 Spring 安全性和 Spring OAuth2 客户端的新 Spring 引导微服务已经很好地实现了这一点,但是将这些库与旧的 Jakarta EE 应用程序集成是一个挑战。

Implementation执行

  • Spring version - 5.3.13 Spring 版本 - 5.3.13
  • Spring Security version - 5.5.3 Spring 安全版 - 5.5.3
  • Omnifaces version - 3.11.2 Omnifaces 版本 - 3.11.2
  • Jakarta EE version - 8 Jakarta EE 版本 - 8
  • Wildfly application container - 23 Wildfly 应用程序容器 - 23
  1. There is an existing Authentication system using Java EE HttpAuthenticationMechanism with a AuthenticatedUser bean which acts like a principal.现有的身份验证系统使用 Java EE HttpAuthenticationMechanism 和 AuthenticatedUser bean,其作用类似于主体。
  2. I added Spring security and OAuth2 client to the Java EE application.我将 Spring 安全和 OAuth2 客户端添加到 Java EE 应用程序。 It works fine and redirects people to an AWS Cognito SSO page and redirects back with authorization code after they login.它工作正常并将人们重定向到 AWS Cognito SSO 页面,并在他们登录后使用授权代码重定向回来。

Here is a diagram summarizing what is currently hacked together这是一个图表,总结了当前被黑客攻击的内容

在此处输入图像描述

Testing测试

I created two basic JSF pages with backing beans, one secured with old Javax Security rules defined in web.xml and the other defined in Spring security configuration bean. I created two basic JSF pages with backing beans, one secured with old Javax Security rules defined in web.xml and the other defined in Spring security configuration bean.

With the Spring secured page, I can get the Security context in the bean (I think this uses ThreadLocal)使用 Spring 安全页面,我可以在 bean 中获取安全上下文(我认为这使用 ThreadLocal)

eg Helloworld Backing Bean例如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 Security Config 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();
    }
    ...

However if I don't protect that JSF page with Spring security I cannot get any context.但是,如果我不使用 Spring 安全性保护 JSF 页面,我将无法获得任何上下文。

Problem问题

When a JSF page has been secured with the old security way, it seems to go down a different path with contexts that are all managed by CDI.当 JSF 页面已通过旧的安全方式得到保护时,go 似乎走上了一条不同的路径,其上下文均由 CDI 管理。

I want to integrate Spring security principal into all parts of the JSF app.我想将 Spring 安全主体集成到 JSF 应用程序的所有部分中。 So that JSF is aware of it in its context.因此 JSF 在其上下文中知道它。

Debugging调试

When debugging some existing pages, it appears that both Auth systems are activated but are divergent and not aware of each other.在调试某些现有页面时,似乎两个 Auth 系统都已激活,但存在分歧并且彼此不了解。

Solutions?解决方案?

As someone who has been spoiled by the luxury of spring boot auto configuration, I am a bit stuck on what to do.作为一个被 spring 开机自动配置的奢华宠坏的人,我有点不知道该怎么做。

Potentially its an easy fix with just overriding a class, or:只需覆盖 class 或:

  • Do I need to just rip out the old Authentication system that uses Java EE spec?我是否需要删除使用 Java EE 规范的旧身份验证系统?
  • Do I override some part of Spring security so that it is aware of Java EE and JSF?我是否覆盖 Spring 安全性的某些部分,以便它知道 Java EE 和 JSF?
  • Does JSF need to be configured to talk to Spring security? JSF 是否需要配置为与 Spring 安全通信?
  • Is there something higher level abstracted away in the Wildfly application server that needs to be configured? Wildfly 应用程序服务器中是否有更高级别的抽象需要配置?

tl;dr tl;博士

How do I get Spring security to pass its security context to JSF in a Jakarta EE application?如何在 Jakarta EE 应用程序中获得 Spring 安全性以将其安全上下文传递给 JSF?

Thanks谢谢

A current application running in Wildfly (Jboss) uses its own Authentication system that internally verifies passwords and credentials on its Database.在 Wildfly (Jboss) 中运行的当前应用程序使用其自己的身份验证系统,该系统在内部验证其数据库上的密码和凭据。

From your diagram, it looks like it's not "its own Authentication system", but it uses Java EE Security.从您的图中,它看起来不是“它自己的身份验证系统”,但它使用 Java EE 安全性。 There's no need to replace this with anything Spring.无需将其替换为 Spring。

The best way to make this work is to keep it as is.完成这项工作的最佳方法是保持原样。 Java EE Security was specifically designed to work with JSF, and the two integrate together quite well. Java EE Security 专为与 JSF 一起工作而设计,两者很好地集成在一起。 Bringing your own security system into the mix here is probably asking for problems later.在这里加入您自己的安全系统可能会在以后提出问题。

ps ps

OpenId Connect is currently being included in what's now called Jakarta EE Security, see https://github.com/jakartaee/security/pull/185 OpenId Connect 目前包含在现在称为 Jakarta EE 安全性中,请参阅https://github.com/jakartaee/security/pull/185

Java EE Security on WildFly works really well with the MicroProfile APIs, which includes a JWT Authentication Mechanism. WildFly 上的 Java EE 安全性与 MicroProfile API 配合得非常好,其中包括 JWT 身份验证机制。 See for example参见例如

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM