Search code examples
spring-bootkeycloakspring-security-oauth2

How to correctly configure spring `oauth2Login` with SSL enabled?


I'm trying to configure an OAuth2 client with spring-boot, but couldn't configure oauth2Login() correctly: when trying to access https://localhost:8080, I keep being redirected to https://localhost:8443/oauth2/authorization/spring-addons-public to initiate login, when I'd expect to be first redirected to https://localhost:8080/oauth2/authorization/spring-addons-public (mind the port 8080 which is Spring client's one) which, in turn, should redirect me to https://localhost:8443/realms/master/protocol/openid-connect/auth (this is configured authorization-uri, 8443 being the port of authorization-server).

If I explicitely visit https://localhost:8080/oauth2/authorization/spring-addons-public, then authentication-code flow is correctly initiated.

What did I miss?

Simplest reproducer:

<?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.0.0</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <artifactId>demo</artifactId>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
spring:
  security:
    oauth2:
      client:
        registration:
          spring-addons-public:
            client-id: "spring-addons-public"
            client-secret: ""
            client-name: "spring-addons-public"
            provider: "keycloak"
            scope: 
              - "openid"
              - "profile"
            redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
            client-authentication-method: "none"
            authorization-grant-type: "authorization_code"

        provider:
          keycloak:
            issuer-uri: "https://localhost:8443/realms/master"
            authorization-uri: "https://localhost:8443/realms/master/protocol/openid-connect/auth"
            token-uri: "https://localhost:8443/realms/master/protocol/openid-connect/token"
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    SecurityFilterChain uiFilterChain(HttpSecurity http) throws Exception {
        // @formatter:off
        http.authorizeHttpRequests()
            .requestMatchers("/oauth2/**").permitAll()
            .requestMatchers("/login/**").permitAll()
            .anyRequest().authenticated();
        // @formatter:on
        http.oauth2Login();

        return http.build();
    }
}

src/main/resources/static/index.html:

<!DOCTYPE html>
<head>
    <title>secured</title>
</head>
<body>
    <h1>Secured</h1>
</body>

Edit

SSL is enabled by default for my spring-boot apps (I have set SERVER_SSL_KEY_PASSWORD, SERVER_SSL_KEY_STORE and SERVER_SSL_KEY_STORE_PASSWORD environement variables). I figured out that redirections are done to the right port if I explicitely disable SSL with server.ssl.enabled=false.


Solution

  • I found a way to force the first redirect port in Java conf:

        http.oauth2Login().loginPage("https://localhost:8080/oauth2/authorization/spring-addons-public");
    

    I still don't understand why, when SSL is enabled on the client, default configuration redirects to the authorization-server socket (instead of the client socket where the default login page is generated).

    And it's the same with the post login redirect (after authorization code was sucessfully exchanged for tokens): I am redirected to the authorization-server index when I'd expect to be redirected to client's index.

    I opened a ticket for that.