Exception when using PreAuthorize annotation alongwith path-variables that contian special characters

43 Views Asked by At

Here is my set-up:

  1. We have a spring-boot application 2.6.4.

  2. It has a RestController class with a GET api endpoint as /v1/permissions/{appname}/users/{username}, where appname and username are path-variables.

  3. This controller has a @PreAuthorize annotation like this: @PreAuthorize("hasAnyAuthority('/v1/permissions/member', '/v1/permissions/colt')")

  4. Now when we hit the API with path /v1/permissions/member/users/krishna it works perfectly fine and gives us the output.

  5. But when we hit the API with path /v1/permissions/member/users/[email protected] it gives the following error:

    org.apache.juli.logging.DirectJDKLog#log:175 - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext] with root cause |
    org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
    
  6. After some analysis we found that the above error occurs only when we are using the "@PreAuthorize annotation" alongwith special characters in "username" path-variable, that is only this combination of annotation and path-variable gives the error.

  7. But this error doesn't occur with the following combinations:

    • "@PreAuthorize annotation" and using "username" as a request-parameter with any type of special characters
    • without "@PreAuthorize annotation" and using "username" as path-variable with any type of special characters.
  8. Also we tried debugging the issue and found out that it doesn't even go in any of our custom Authentication Provider or Custom filters when the exception occurs.

If it helps here is my SecurityConfig class:

    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {

        @Autowired
        private CustomAuthenticationProvider customAuthenticationProvider;

        private static final String[] AUTH_WHITELIST = { "/v3/api-docs", "/configuration/ui",
                "/swagger-resources/**", "/swagger-resources", "/configuration/security",
                "/swagger-ui/**", "/webjars/**" };

        @Override
        protected void configure(final HttpSecurity http) throws Exception {

            http.csrf().disable().headers().disable().authorizeRequests().antMatchers(AUTH_WHITELIST).permitAll()
                    .anyRequest().authenticated().and()
                    .addFilterBefore(new CustomHeaderAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);

        }

        @Override
        public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(customAuthenticationProvider);

        }

        @Override
        public void configure(WebSecurity web) throws Exception {

            web.ignoring()

                    .antMatchers("/**/*.{js,html,css}",
                            "/error",
                            "/v3/api-docs",
                            "/configuration/ui",
                            "/swagger-resources/**",
                            "/swagger-resources",
                            "/configuration/security",
                            "/swagger-ui/**",
                            "/webjars/**",
                            "/monitor/health",
                            "/monitor/db/health");

        }

    }

Now my questions are:

  1. Why does this happen?
  2. How can i resolve it i.e. i want to use "@PreAuthorize annotation" in combination with path-variables only.

Thank You

0

There are 0 best solutions below