Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support RoleHierarchy Bean in authorizeHttpRequests Kotlin DSL #15136

Closed
ttasjwi opened this issue May 23, 2024 · 3 comments
Closed

Support RoleHierarchy Bean in authorizeHttpRequests Kotlin DSL #15136

ttasjwi opened this issue May 23, 2024 · 3 comments
Assignees
Labels
in: config An issue in spring-security-config type: enhancement A general enhancement
Milestone

Comments

@ttasjwi
Copy link

ttasjwi commented May 23, 2024

Hello, Spring Security Team.

I have encountered an issue when configuring security with Kotlin DSL and RoleHierarchy. The behavior seems inconsistent compared to the traditional DSL configuration.

Controller

@RestController
class SecurityController {

    @GetMapping("/")
    fun index(): String {
        return "index"
    }

    @GetMapping("/user")
    fun user(): String {
        return "user"
    }

    @GetMapping("/db")
    fun db(): String {
        return "db"
    }

    @GetMapping("/admin")
    fun admin(): String {
        return "admin"
    }
}

UserDetailsService

    @Bean
    fun userDetailsService(): UserDetailsService {
        val user = User.withUsername("user").password("{noop}1111").roles("USER").build()
        val db = User.withUsername("db").password("{noop}1111").roles("DB").build()
        val admin = User.withUsername("admin").password("{noop}1111").roles("ADMIN").build()
        return InMemoryUserDetailsManager(user, db, admin)
    }

RoleHierarchy Bean

The RoleHierarchy bean is configured as follows:

    @Bean
    fun roleHierarchy(): RoleHierarchy {
        val roleHierarchy = RoleHierarchyImpl()
        roleHierarchy.setHierarchy(
            """
            ROLE_ADMIN > ROLE_DB
            ROLE_DB > ROLE_USER
            ROLE_USER > ROLE_ANONYMOUS
        """.trimIndent()
        )
        return roleHierarchy
    }

Traditional DSL Configuration

Using the traditional DSL configuration, RoleHierarchy works as expected:

@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
    http.authorizeHttpRequests {
        it
            .requestMatchers("/user").hasRole("USER")
            .requestMatchers("/admin").hasRole("ADMIN")
            .requestMatchers("/db").hasRole("DB")
    }
        .formLogin(Customizer.withDefaults())
        .csrf { it.disable() }
    return http.build()
}

Kotlin DSL Configuration

However, when using the Kotlin DSL configuration, the RoleHierarchy seems to behave inconsistently:

import org.springframework.security.config.annotation.web.invoke

@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
    http {
        authorizeHttpRequests {
            authorize("/user", hasRole("USER"))
            authorize("/admin", hasRole("ADMIN"))
            authorize("/db", hasRole("DB"))
            authorize(anyRequest, authenticated)
        }
        formLogin { }
        csrf { disable() }
    }
    return http.build()
}

Environment

  • Spring Boot : 3.2.5
  • spring security: 6.2.4
  • kotlin version : 1.9.23
@ttasjwi ttasjwi added status: waiting-for-triage An issue we've not yet triaged type: bug A general bug labels May 23, 2024
@marcusdacoregio
Copy link
Contributor

Hi, @ttasjwi. Thanks for the report.

Can you clarify what is inconsistent between the two configurations?

@marcusdacoregio marcusdacoregio added status: waiting-for-feedback We need additional information before we can continue and removed status: waiting-for-triage An issue we've not yet triaged labels May 23, 2024
@marcusdacoregio marcusdacoregio self-assigned this May 23, 2024
@ttasjwi
Copy link
Author

ttasjwi commented May 23, 2024

Hi, @ttasjwi. Thanks for the report.

Can you clarify what is inconsistent between the two configurations?

Hi,

To clarify the inconsistencies between the two configurations:

When using the traditional DSL configuration, the RoleHierarchy works as expected. However, when using the Kotlin DSL configuration, the RoleHierarchy seems to behave inconsistently. For example, an ADMIN user should be able to access the /user endpoint, but in practice, this is not always the case.

Here's a summary of the issue I’m encountering:

  • Traditional DSL Configuration: The RoleHierarchy is properly applied, and an ADMIN user can access endpoints that a DB or USER role can access.
  • Kotlin DSL Configuration: The RoleHierarchy does not seem to work as expected. An ADMIN user is unable to access certain endpoints that should be accessible based on the RoleHierarchy.

The only difference between the two setups is the declaration of the securityFilterChain method. All other components, including the Controller, UserDetailsService, and RoleHierarchy bean, remain the same.

Here are the two securityFilterChain configurations for comparison:

Traditional DSL Configuration

@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
    http.authorizeHttpRequests {
        it
            .requestMatchers("/user").hasRole("USER")
            .requestMatchers("/admin").hasRole("ADMIN")
            .requestMatchers("/db").hasRole("DB")
    }
        .formLogin(Customizer.withDefaults())
        .csrf { it.disable() }
    return http.build()
}

Kotlin DSL Configuration

import org.springframework.security.config.annotation.web.invoke

@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
    http {
        authorizeHttpRequests {
            authorize("/user", hasRole("USER"))
            authorize("/admin", hasRole("ADMIN"))
            authorize("/db", hasRole("DB"))
            authorize(anyRequest, authenticated)
        }
        formLogin { }
        csrf { disable() }
    }
    return http.build()
}

I would like to know if I am missing something in my Kotlin DSL configuration or if there are additional steps required to properly set up the RoleHierarchy in Kotlin DSL.

Thank you for your assistance.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels May 23, 2024
@marcusdacoregio
Copy link
Contributor

Hi @ttasjwi. I see that there is no support for RoleHierarchy bean in the authorizeHttpRequests Kotlin DSL. The issue #13188 has added it but only to the Java DSL.

I'll repurpose this ticket to add the support to the Kotlin DSL.

@marcusdacoregio marcusdacoregio changed the title Inconsistent RoleHierarchy Behavior with Kotlin DSL Configuration Support RoleHierarchy Bean in authorizeHttpRequests Kotlin DSL May 23, 2024
@marcusdacoregio marcusdacoregio added in: config An issue in spring-security-config type: enhancement A general enhancement and removed type: bug A general bug status: feedback-provided Feedback has been provided labels May 23, 2024
@marcusdacoregio marcusdacoregio added this to the 6.4.0-M1 milestone May 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: config An issue in spring-security-config type: enhancement A general enhancement
Projects
Status: Done
Development

No branches or pull requests

3 participants