Search code examples
javaspring-securitybasic-authenticationspring-boot-security

authenticationEntryPoint won't work for permit() http method with credentials submitted


@Override
   protected void configure(HttpSecurity httpSecurity) throws Exception
   {
      // @formatter:off
      httpSecurity
               .csrf()
               .disable()
               .authorizeRequests()
               .antMatchers(HttpMethod.GET).permitAll()
               .anyRequest()
               .authenticated()
               .and()
               .httpBasic()
               .and()
               .exceptionHandling()
               .authenticationEntryPoint(authenticationEntryPoint());
      // @formatter:on
   }

   private static AuthenticationEntryPoint authenticationEntryPoint()
   {
      return (request, response, authException) -> {
         response.addHeader("WWW-Authenticate", "Basic realm=\"Realm\"");
         response.setContentType(MediaType.APPLICATION_JSON_VALUE);
         response.setStatus(HttpStatus.UNAUTHORIZED.value());
         String message = authException.getMessage();
         if (request.getHeaders("Authorization").hasMoreElements()) {
            message += ". Wrong Authorization Key.";
         } else {
            message += ". Missing Authorization Key im Header.";
         }
         response.getWriter().format("""
                                              {
                                                "errors":[
                                                  {
                                                    "status": %d,
                                                    "title": "%s",
                                                    "detail": "%s"
                                                  }
                                                ]
                                              }
                                              """,
                                     HttpStatus.UNAUTHORIZED.value(),
                                     HttpStatus.UNAUTHORIZED.name(),
                                     message
         );
      };
   }

why i send a post request with wrong credentials, i got:

{
    "errors": [
        {
            "status": 401,
            "title": "UNAUTHORIZED",
            "detail": "Full authentication is required to access this resource. Wrong Authorization Key."
        }
    ]
}

for a get method i don't get a formatted error:

{
    "timestamp": "2023-04-18T17:07:35.663+00:00",
    "status": 401,
    "error": "Unauthorized",
    "path": "/xxx/1111"
}

I also get a pretty response like a post


Solution

  • There is a known bug/feature in spring security that causes a request to be ‘validated’ if it has an Authorization header long before the permitAll() is hit. I believe that is what we have observed. Don’t pass credentials unless they are valid.