Run a Spring Boot oAuth2 application as resource server AND serving web content

后端 未结 1 1651
别跟我提以往
别跟我提以往 2021-01-06 13:07

I\'m using Spring Boot 1.5.13 and with that Spring Security 4.2.6 and Spring Security oAuth2 2.0.15.

I want to find a best practice setup for our Spring Boot applica

1条回答
  •  有刺的猬
    2021-01-06 13:38

    I found the solution: It takes multiple HttpSecurity configurations. I found out by reading the great article written by Matt Raible at https://developer.okta.com/blog/2018/02/13/secure-spring-microservices-with-oauth where he introduced me to the notion of requestMatchers(.). This is how I finally implemented it:

     @Configuration
     @EnableResourceServer
     @EnableWebSecurity(debug = true)
     @EnableOAuth2Sso
     public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    
         @Bean
         public RequestContextListener requestContextListener() {
             return new RequestContextListener();
         }
    
         @Override
         public void configure(HttpSecurity http) throws Exception {
             http
                 .requestMatcher(new RequestHeaderRequestMatcher("Authorization"))
                 .authorizeRequests().anyRequest().fullyAuthenticated();
         }
    
     }
    

    With that I can access the service with a Browser, leading to a authorization code flow. But accessing the API (or actually any part of the service) leads to a validation of the provided Bearer token.

    And to illustrate the way how some endpoints can be exluded/made public in such a case, here's how I configure the actuator endpoints and one very simple 'ping' endpoint I've added myself:

     @Configuration
     @Order(1)
     public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.requestMatcher(new OrRequestMatcher(EndpointRequest.to("health", "info"),
                     new AntPathRequestMatcher("/cfhealth"))).authorizeRequests().anyRequest().permitAll();
        }
    
     }
    

    And my implementation of the /cfhealth endpoint:

     @Controller
     @Slf4j
     public class MainController {
    
         @GetMapping(value = "/cfhealth")
         @ResponseBody
         public String cfhealth() {
             return "ok";
         }
    
     }
    

    I'm happy to learn from others if that's the best practice way of Spring Security configuration or if there are better ways to do it. I've spent quite some time on the topic in the last few weeks on it, and it takes quite some effort to grasp the basic Spring Security concepts.

    0 讨论(0)
提交回复
热议问题