1

I support two types of authentication and need to return 401 for most paths instead of redirects. For Keycloak I used the HttpUnauthorizedEntryPoint below and its fine, but for the OAuth2 login, it prevents the automatic redirect (on "/auth/challenge" in my case) to "/oauth2/authorization/azure" on NegatedRequestMatcher(/login, and some other things) to be put in place. The valid process is reflected in logs below:

org.springframework.security.web.util.matcher.NegatedRequestMatcher: matches = true org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint: Match found! Executing org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint@112c824c org.springframework.security.web.context.SecurityContextPersistenceFilter: SecurityContextHolder now cleared, as request processing completed org.springframework.security.web.DefaultRedirectStrategy: Redirecting to 'http://localhost:2222/oauth2/authorization/azure'

This is the code that adds the Ouath2 bit to the common configuration:

    @Throws(Exception::class)
    override fun configure(http: HttpSecurity) {
        http.commonConfiguration()
                .exceptionHandling()
                    .authenticationEntryPoint(HttpUnauthorizedEntryPoint())
                .and()
                .oauth2Login()
                    .userInfoEndpoint()
                    .oidcUserService(userService)
    }


public class HttpUnauthorizedEntryPoint implements AuthenticationEntryPoint {
    private static final Logger LOG = LoggerFactory.getLogger(HttpUnauthorizedEntryPoint.class);

    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException arg) throws IOException {

        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "This endpoint requires authorization.");
    }
}

The question is, how can I by default return 401 and let all the OAuth2 redirects to be placed under the hood?

Thanks in advance.

I know that because of the HttpUnauthorizedEntryPoint the DelegatingAuthenticationEntryPoint is not filled in by Spring Security. I tried to add this manually, but I would rather have this process done by Spring.

val entryPoints = LinkedHashMap<RequestMatcher, AuthenticationEntryPoint>()
entryPoints[loginPageMatcher] = LoginUrlAuthenticationEntryPoint("/oauth2/authorization/azure")
val loginEntryPoint = DelegatingAuthenticationEntryPoint(entryPoints)
loginEntryPoint.setDefaultEntryPoint(HttpUnauthorizedEntryPoint())
marcin
  • 11
  • 2

1 Answers1

0

My guess is you serve both a REST API and server-side rendered UI (Thymeleaf, JSF or whatever) and you want to return

  • 401 for unauthorized requests to @RestController
  • 302 (redirect to login) for unauthorized requests to UI pages.

Define two SecurityFilterChain beans:

  • first with client configuration restricted to UI paths
    • @Order(Ordered.HIGHEST_PRECEDENCE)
    • http.securityMatcher(new OrRequestMatcher(new AntPathRequestMatcher("/login/**"), new AntPathRequestMatcher("/oauth2/**"), ...); // add here all paths to UI resources
    • http.oauth2Login(); // and all client configuration you need for UI
    • http.authorizeHttpRequests().requestMatchers("/login/**").permitAll().requestMatchers("/oauth2/**").permitAll().anyRequest().authenticated();
  • second being default with resource-server configuration (no securityMatcher and an order greater than HIGHEST_PRECEDENCE)

Details in this answer and that tutorial

ch4mp
  • 6,622
  • 6
  • 29
  • 49
  • I can't update my Spring Security at the moment. Any idea on how to solve this in Spring Security 5.7 ? – marcin Jan 30 '23 at 13:46
  • Exactly as I answered. `SecurityFilterChain` has been around for a wile. In 5.7, `WebSecurityConfigurerAdapter` is still there but is already deprecated. – ch4mp Jan 30 '23 at 17:18
  • OK, I just realized that http.securityMatcher is in older version a requestMatcher and authorizeHttpRequests().requestMatchers is in fact antMatcher. I have made such config by changing my old adapters to SecurityFilerChains and it appears to work. – marcin Feb 02 '23 at 10:38