Baeldung / spring-security-oauth

Just Announced - "Learn Spring Security OAuth":
http://bit.ly/github-lsso
MIT License
1.99k stars 1.95k forks source link

oauth-rest oauth-authorization-server Won't start #441

Closed cobar79 closed 12 months ago

cobar79 commented 12 months ago

Spring Boot 3.1.4 Java 17

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.cobar.dp</groupId>
    <artifactId>auth-server</artifactId>
    <version>1.0</version>
    <name>auth-server</name>
    <description>Embedded Keycloak Server IDP.</description>

    <properties>
        <java.version>17</java.version>
        <keycloak.version>22.0.3</keycloak.version>
        <liquibase.version>4.23.2</liquibase.version>
        <resteasy.version>6.2.5.Final</resteasy.version>
    </properties>

    <dependencies>
        <!--#### CONFIGURATION ####-->
        <!-- config properties processor -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <!--#### Security ####-->
        <!-- Embedded Keycloak Server (no keycloak docker container needed) -->
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-dependencies-server-all</artifactId>
            <version>${keycloak.version}</version>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-crypto-default</artifactId>
            <version>${keycloak.version}</version>
        </dependency>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-admin-ui</artifactId>
            <version>${keycloak.version}</version>
        </dependency>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-services</artifactId>
            <version>${keycloak.version}</version>
        </dependency>
        <dependency>
            <groupId>org.keycloak</groupId>
            <artifactId>keycloak-rest-admin-ui-ext</artifactId>
            <version>${keycloak.version}</version>
        </dependency>

        <!--### PERSISTENCE ####-->
        <!-- Keycloak persistence -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.liquibase</groupId>
            <artifactId>liquibase-core</artifactId>
            <version>${liquibase.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.yaml</groupId>
                    <artifactId>snakeyaml</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.commons</groupId>
                    <artifactId>commons-text</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!--#### REST ####-->
        <!-- Tomcat -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jackson2-provider</artifactId>
            <version>${resteasy.version}</version>
        </dependency>

        <!--#### UTILITIES ####-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--#### TESTING ####-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>rest-assured</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.cobar.dp.auth.AuthServerApplication</mainClass>
                    <requiresUnpack>
                        <dependency>
                            <groupId>org.keycloak</groupId>
                            <artifactId>keycloak-model-jpa</artifactId>
                        </dependency>
                    </requiresUnpack>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>**/*LiveTest.java</exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
@Slf4j
@Configuration
public class EmbeddedKeycloakConfig {

    @Bean
    ServletRegistrationBean<HttpServlet30Dispatcher> keycloakJaxRsApplication(
            KeycloakServerProperties keycloakServerProperties, DataSource dataSource) throws Exception {

        mockJndiEnvironment(dataSource);
        EmbeddedKeycloakApplication.keycloakServerProperties = keycloakServerProperties;

        ServletRegistrationBean<HttpServlet30Dispatcher> servlet = new ServletRegistrationBean<>(
                new HttpServlet30Dispatcher());
        servlet.addInitParameter("jakarta.ws.rs.Application", EmbeddedKeycloakApplication.class.getName());
        servlet.addInitParameter(ResteasyContextParameters.RESTEASY_SERVLET_MAPPING_PREFIX,
                keycloakServerProperties.getContextPath());
        servlet.addInitParameter(ResteasyContextParameters.RESTEASY_USE_CONTAINER_FORM_PARAMS, "true");
        servlet.addUrlMappings(keycloakServerProperties.getContextPath() + "/*");
        servlet.setLoadOnStartup(1);
        servlet.setAsyncSupported(true);

        return servlet;
    }

    @Bean
    FilterRegistrationBean<EmbeddedKeycloakRequestFilter> keycloakSessionManagement(KeycloakServerProperties keycloakServerProperties) {

        FilterRegistrationBean<EmbeddedKeycloakRequestFilter> filter = new FilterRegistrationBean<>();
        filter.setName("Keycloak Session Management");
        filter.setFilter(new EmbeddedKeycloakRequestFilter());
        filter.addUrlPatterns(keycloakServerProperties.getContextPath() + "/*");

        return filter;
    }

    private void mockJndiEnvironment(DataSource dataSource) throws NamingException {
        NamingManager.setInitialContextFactoryBuilder(env -> environment -> new InitialContext() {

            @Override
            public Object lookup(Name name) {
                return lookup(name.toString());
            }

            @Override
            public Object lookup(String name) {

                if ("spring/datasource".equals(name)) {
                    return dataSource;
                } else if (name.startsWith("java:jboss/ee/concurrency/executor/")) {
                    return fixedThreadPool();
                }

                return null;
            }

            @Override
            public NameParser getNameParser(String name) {
                return CompositeName::new;
            }

            @Override
            public void close() {
                // NOOP
            }
        });
    }

    @Bean("fixedThreadPool")
    public ExecutorService fixedThreadPool() {
        return Executors.newFixedThreadPool(5);
    }

    @Bean
    @ConditionalOnMissingBean(name = "springBootPlatform")
    protected SimplePlatformProvider springBootPlatform() {
        return (SimplePlatformProvider) Platform.getPlatform();
    }
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springBootPlatform' defined in class path resource [com/cobar/dp/auth/config/EmbeddedKeycloakConfig.class]: Failed to instantiate [com.cobar.dp.auth.config.SimplePlatformProvider]: Factory method 'springBootPlatform' threw exception with message: No PlatformProvider found
        at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:654) ~[spring-beans-6.0.12.jar:6.0.12]
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:488) ~[spring-beans-6.0.12.jar:6.0.12]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1332) ~[spring-beans-6.0.12.jar:6.0.12]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1162) ~[spring-beans-6.0.12.jar:6.0.12]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) ~[spring-beans-6.0.12.jar:6.0.12]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[spring-beans-6.0.12.jar:6.0.12]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[spring-beans-6.0.12.jar:6.0.12]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.12.jar:6.0.12]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[spring-beans-6.0.12.jar:6.0.12]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-6.0.12.jar:6.0.12]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:973) ~[spring-beans-6.0.12.jar:6.0.12]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:942) ~[spring-context-6.0.12.jar:6.0.12]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608) ~[spring-context-6.0.12.jar:6.0.12]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.1.4.jar:3.1.4]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) ~[spring-boot-3.1.4.jar:3.1.4]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.1.4.jar:3.1.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-3.1.4.jar:3.1.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1309) ~[spring-boot-3.1.4.jar:3.1.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1298) ~[spring-boot-3.1.4.jar:3.1.4]
        at com.cobar.dp.auth.AuthServerApplication.main(AuthServerApplication.java:20) ~[classes/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.cobar.dp.auth.config.SimplePlatformProvider]: Factory method 'springBootPlatform' threw exception with message: No PlatformProvider found
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:171) ~[spring-beans-6.0.12.jar:6.0.12]
        at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:650) ~[spring-beans-6.0.12.jar:6.0.12]
        ... 19 common frames omitted
Caused by: java.lang.RuntimeException: No PlatformProvider found
        at org.keycloak.platform.Platform.getPlatform(Platform.java:34) ~[keycloak-services-22.0.3.jar:22.0.3]
        at com.cobar.dp.auth.config.EmbeddedKeycloakConfig.springBootPlatform(EmbeddedKeycloakConfig.java:100) ~[classes/:na]
        at com.cobar.dp.auth.config.EmbeddedKeycloakConfig$$SpringCGLIB$$0.CGLIB$springBootPlatform$0(<generated>) ~[classes/:na]
        at com.cobar.dp.auth.config.EmbeddedKeycloakConfig$$SpringCGLIB$$2.invoke(<generated>) ~[classes/:na]
        at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:258) ~[spring-core-6.0.12.jar:6.0.12]
        at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-6.0.12.jar:6.0.12]
        at com.cobar.dp.auth.config.EmbeddedKeycloakConfig$$SpringCGLIB$$0.springBootPlatform(<generated>) ~[classes/:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:139) ~[spring-beans-6.0.12.jar:6.0.12]
        ... 20 common frames omitted
ulisseslima commented 12 months ago

Hey, @cobar79.

Please also include the link to the tutorial you were following.

Also, does it work with the code on the repository without modifications?

cobar79 commented 12 months ago

https://www.baeldung.com/spring-cloud-gateway-oauth2 https://www.baeldung.com/keycloak-embedded-in-spring-boot-app

Your clone of oauth-rest/oauth-authorization-server does work. However, I decided to just go with the Keycloak Image over an embedded one.

Your post always seem to not match the source code. I can't find the Gateway project as Resource Server in the https://github.com/Baeldung/spring-security-oauth/tree/master. The link in https://www.baeldung.com/spring-cloud-gateway-oauth2 to github is no good, just takes to root of all projects.

lor6 commented 11 months ago

Hi @cobar79 The article https://www.baeldung.com/spring-cloud-gateway-oauth2 links to the project: https://github.com/eugenp/tutorials/tree/master/spring-cloud-modules/spring-cloud-gateway - this is where you'll find the Gateway project as Resource Server.

cobar79 commented 11 months ago

While the post is informative, unfortunately, the repo is too hard to decrypt to find what I want to implement.

It is a common pattern with Baeldung posts. I tend to bypass and go with Medium repository

On Tue, Oct 10, 2023, 1:51 AM Loredana Crusoveanu @.***> wrote:

Hi @cobar79 https://github.com/cobar79 The article https://www.baeldung.com/spring-cloud-gateway-oauth2 links to the project: https://github.com/eugenp/tutorials/tree/master/spring-cloud-modules/spring-cloud-gateway

  • this is where you'll find the Gateway project as Resource Server.

— Reply to this email directly, view it on GitHub https://github.com/Baeldung/spring-security-oauth/issues/441#issuecomment-1754611781, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKG2SZP7VSL5B3P5U5EWFP3X6T5B5AVCNFSM6AAAAAA5RYO5G2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONJUGYYTCNZYGE . You are receiving this because you were mentioned.Message ID: @.***>