spring-security icon indicating copy to clipboard operation
spring-security copied to clipboard

Remove default value for access parameter

Open ysavchen opened this issue 3 years ago • 0 comments

Closes gh-10957

The test below shows the issue with "authenticated" access as a default parameter. After fix the test is not relevant as the problem is solved at the compilation phase. This is a breaking change, for example, when a user has authorize("/path") instead of authorize("/path", authenticated) in config.

@Test
fun `request when authorize with servletPath and default access`() {
    this.spring.register(ServletPathAndDefaultAccessConfig::class.java).autowire()

    this.mockMvc.perform(MockMvcRequestBuilders.get("/servletPath/path")
        .with { request ->
            request.servletPath = "/servletPath"
            request
        })
        .andExpect(status().isUnauthorized)

    this.mockMvc.perform(MockMvcRequestBuilders.get("/servletPath/path")
        .with(httpBasic("user", "password"))
        .with { request ->
            request.servletPath = "/servletPath"
            request
        })
        .andExpect(status().isOk)
}

@EnableWebSecurity
@EnableWebMvc
open class ServletPathAndDefaultAccessConfig {
    @Bean
    open fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            authorizeRequests {
                // before fix:
                // a user intends to invoke authorize(pattern, servletPath, access ["authenticated" by default]),
                // but in fact get authorize(pattern, access)
                authorize("/path", "/servletPath")

                // after fix:
                // a user must explicitly specify "authenticated" to invoke authorize(pattern, servletPath, access)
                authorize("/path", "/servletPath", authenticated)
            }
            httpBasic { }
        }
        return http.build()
    }

    @RestController
    internal class PathController {
        @GetMapping("/path")
        fun path() {
        }
    }

    @Bean
    open fun userDetailsService(): UserDetailsService {
        val userDetails = User.withDefaultPasswordEncoder()
            .username("user")
            .password("password")
            .roles("USER")
            .build()
        return InMemoryUserDetailsManager(userDetails)
    }
}

ysavchen avatar Jul 20 '22 13:07 ysavchen