当前位置: 首页 > 知识库问答 >
问题:

我们可以在Quarkus中使用spring-security-SAML 2-service-provider吗

慕容劲
2023-03-14

我们是Quarkus的新手,并用它来构建一个简单的服务提供商,用于通过SAML协议进行单点登录,并将Okta作为身份提供商。不幸的是,夸库只支持开放Id连接(我们找不到任何SAML协议的指南)。但是,Spring已经在Spring安全saml2-服务提供商中实现了这一点,因此我们希望在Quarkus上重用此Spring组件。

我们在项目中只有1个简单的(SpringRest)控制器:

import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import io.quarkus.qute.CheckedTemplate;
import io.quarkus.qute.TemplateInstance;

@RestController
@RequestMapping("/greeting")
public class GreetingController {

    @CheckedTemplate
    public static class Templates {
        public static native TemplateInstance hello();
    }

    @RequestMapping("/")
    public TemplateInstance index() {
        return Templates.hello();
    }

    @RequestMapping("/secured/hello")
    public String hello(@AuthenticationPrincipal Saml2AuthenticatedPrincipal principal) {
        return "hello" + principal.getName();
    }
}

以及application.properties下OKTA的一些其他配置:

spring.security.saml2.relyingparty.registration.okta-saml.identityprovider.entity-id=<censored-value>
spring.security.saml2.relyingparty.registration.okta-saml.identityprovider.entity-id.verification.credentials.certificate-location="classpath:saml-certificate/okta.crt"
spring.security.saml2.relyingparty.registration.okta-saml.identityprovider.entity-id.singlesignon.url=<censored-value>
spring.security.saml2.relyingparty.registration.okta-saml.identityprovider.entity-id.singlesignon.sign-request=false

不幸的是,当我们尝试运行mvn quarkus:dev时,系统显示了以下错误stacktrace:

2021-10-13 11:28:01,378 ERROR [io.qua.run.boo.StartupActionImpl] (Quarkus Main Thread) Error running Quarkus: java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at io.quarkus.runner.bootstrap.StartupActionImpl$1.run(StartupActionImpl.java:103)
        at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.ExceptionInInitializerError
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
        at java.base/java.lang.Class.newInstance(Class.java:584)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:65)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:42)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:119)
        at io.quarkus.runner.GeneratedMain.main(GeneratedMain.zig:29)
        ... 6 more
Caused by: java.lang.RuntimeException: Failed to start quarkus
        at io.quarkus.runner.ApplicationImpl.<clinit>(ApplicationImpl.zig:390)
        ... 15 more
Caused by: java.lang.NoClassDefFoundError: org/springframework/security/core/AuthenticatedPrincipal
        at java.base/java.lang.ClassLoader.defineClass1(Native Method)
        at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
        at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:445)
        at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:405)
        at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:455)
        at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:405)
        at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
        at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3166)
        at java.base/java.lang.Class.privateGetPublicMethods(Class.java:3191)
        at java.base/java.lang.Class.getMethods(Class.java:1904)
        at org.jboss.resteasy.spi.metadata.ResourceBuilder.fromAnnotations(ResourceBuilder.java:908)
        at org.jboss.resteasy.spi.metadata.ResourceBuilder.getRootResourceFromAnnotations(ResourceBuilder.java:878)
        at org.jboss.resteasy.plugins.server.resourcefactory.POJOResourceFactory.<init>(POJOResourceFactory.java:41)
        at org.jboss.resteasy.core.ResourceMethodRegistry.addPerRequestResource(ResourceMethodRegistry.java:92)
        at org.jboss.resteasy.core.ResteasyDeploymentImpl.registerResources(ResteasyDeploymentImpl.java:557)
        at org.jboss.resteasy.core.ResteasyDeploymentImpl.registration(ResteasyDeploymentImpl.java:475)
        at org.jboss.resteasy.core.ResteasyDeploymentImpl.startInternal(ResteasyDeploymentImpl.java:164)
        at org.jboss.resteasy.core.ResteasyDeploymentImpl.start(ResteasyDeploymentImpl.java:121)
        at io.quarkus.resteasy.runtime.standalone.ResteasyStandaloneRecorder.staticInit(ResteasyStandaloneRecorder.java:36)
        at io.quarkus.deployment.steps.ResteasyStandaloneBuildStep$staticInit345281060.deploy_0(ResteasyStandaloneBuildStep$staticInit345281060.zig:991)
        at io.quarkus.deployment.steps.ResteasyStandaloneBuildStep$staticInit345281060.deploy(ResteasyStandaloneBuildStep$staticInit345281060.zig:40)
        at io.quarkus.runner.ApplicationImpl.<clinit>(ApplicationImpl.zig:359)
        ... 15 more
Caused by: java.lang.ClassNotFoundException: org.springframework.security.core.AuthenticatedPrincipal
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
        at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:455)
        at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:405)
        ... 37 more

我的问题是:

  1. 是否可以在Quarkus上使用spring-security-saml2-service-provider?或:
  2. 有没有办法让Quarkus使用SAML协议进行单点登录

以下是我们的pom.xml:

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
  xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.acme</groupId>
  <artifactId>spring-security-quickstart</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <properties>
    <compiler-plugin.version>3.8.1</compiler-plugin.version>
    <maven.compiler.parameters>true</maven.compiler.parameters>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
    <quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
    <quarkus.platform.version>2.3.0.Final</quarkus.platform.version>
    <surefire-plugin.version>3.0.0-M5</surefire-plugin.version>
  </properties>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>${quarkus.platform.group-id}</groupId>
        <artifactId>${quarkus.platform.artifact-id}</artifactId>
        <version>${quarkus.platform.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-spring-security</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-elytron-security-properties-file</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-spring-web</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-arc</artifactId>
    </dependency>

    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy-qute</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-saml2-service-provider</artifactId>
      <version>5.5.2</version>
    </dependency>


  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>${quarkus.platform.group-id}</groupId>
        <artifactId>quarkus-maven-plugin</artifactId>
        <version>${quarkus.platform.version}</version>
        <extensions>true</extensions>
        <executions>
          <execution>
            <goals>
              <goal>build</goal>
              <goal>generate-code</goal>
              <goal>generate-code-tests</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${compiler-plugin.version}</version>
        <configuration>
          <parameters>${maven.compiler.parameters}</parameters>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${surefire-plugin.version}</version>
        <configuration>
          <systemPropertyVariables>
            <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
            <maven.home>${maven.home}</maven.home>
          </systemPropertyVariables>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <profiles>
    <profile>
      <id>native</id>
      <activation>
        <property>
          <name>native</name>
        </property>
      </activation>
      <build>
        <plugins>
          <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>${surefire-plugin.version}</version>
            <executions>
              <execution>
                <goals>
                  <goal>integration-test</goal>
                  <goal>verify</goal>
                </goals>
                <configuration>
                  <systemPropertyVariables>
                    <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
                    <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                    <maven.home>${maven.home}</maven.home>
                  </systemPropertyVariables>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
      <properties>
        <quarkus.package.type>native</quarkus.package.type>
      </properties>
    </profile>
  </profiles>
</project>

共有2个答案

隆芷阳
2023-03-14

我在Zulip聊天中也问过这个问题,这是我从Quarkus团队得到的答案:

一种选择是使用夸克-oidc并配置Keycloak(或其他OIDC提供程序)以联合到您的SAML提供程序;大多数好的OIDC提供程序都可以做到这一点

澹台宾白
2023-03-14

在Quarkus中使用Spring Security提供程序将不起作用。

我建议在GitHub上打开一个问题,要求在Quarkus中提供SAML支持

 类似资料:
  • As noted throughout this documentation, Flarum uses Laravel's service container (or IoC container) for dependency injection. Service Providers allow low-level configuration and modification of the Fla

  • 问题内容: 我知道Python提供了API,因此您可以在C代码中调用Python解释器,但是我想要的却是相反的。 我的程序需要使用一些C API,所以代码必须用C编写。但是我也想用Python打包程序。这意味着我想在Python中调用这些C函数或可执行文件。那可能吗? 如果我希望C代码成为一个库,这意味着我将它与Python 中的可能的链接一起使用,该怎么做?那可能吗?如果我将C代码写入可执行文件

  • 本文向大家介绍我们可以在MySQL中使用ORDER BY NULL吗?,包括了我们可以在MySQL中使用ORDER BY NULL吗?的使用技巧和注意事项,需要的朋友参考一下 是的,我们可以做到 注–在MySQL 5.7之前,ORDER BY NULL很有用,但在MySQL 8.0中,例如,最后不需要指定ORDER BY NULL以抑制隐式排序。 让我们首先创建一个表- 使用插入命令在表中插入一些

  • 在我的Spring启动kafka发布者应用程序中,我希望支持以字符串(json)或字节格式发布消息,因为我希望同时支持json和avro。但spring boot中的Kafka模板让我们只定义其中一个模板。有没有一种方法可以同时使用两个模板或任何其他方式来提供对json和avro的支持?

  • 根据线程的名称,我想使用SpringBoot创建一个JAVA库。我发现了这个线索:使用SpringBoot创建一个库jar。然而,该线程的目标似乎可以通过将其实现为RESTAPI来解决。 目前,我正在使用SpringBoot开发一个基于Spring的JAVA库。而且,我尝试将其打包为jar文件,并让另一个JAVA应用程序在JAVA库中使用它。不幸的是,我发现当调用方应用程序调用添加的库的某些方法时

  • 我正在努力使我的Spring Boot(v.2.0.1)应用程序与SSO提供程序一起工作。当我尝试点击登录页面时,我得到以下错误: 在此过程中,某些entityID丢失并创建了这些错误。我似乎无法追踪这是怎么发生的。