Spring Security Spring OAuth2.0:Spring Authorization Server 1.0和资源服务器位于同一个 Boot 应用程序中

c90pui9n  于 2023-01-26  发布在  Spring
关注(0)|答案(1)|浏览(228)

我很难将同一个 Boot 应用程序同时用作身份验证服务器和资源服务器,但直到现在,我还不能使整个应用程序正常工作。
首先,我定义了一个非常简单的RestController:

@RestController
@RequestMapping("api")
public class PublicAPI {
        
    @GetMapping("/apitest")
    public String test(Principal principal) {
        return " This is a test ==>";
    }
}

然后,基本上按照Spring的一个Sample项目中的代码,我成功地将 Boot 应用设置为Spring Authorization Server。我能够使用Postman通过Oauth2流获得身份验证令牌:我被重定向到Spring的标准登录页面,使用凭据登录,并获得令牌。
问题是,如果我尝试使用提供的令牌访问GET http://localhost:9000/api/apitest,我会从Sping Boot 中得到401响应。
这是我的安全配置:

@Bean 
    @Order(1)
    public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http, CorsConfiguration configCors) throws Exception {
        OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
        http.getConfigurer(OAuth2AuthorizationServerConfigurer.class).oidc(Customizer.withDefaults());
        http
            .exceptionHandling((exceptions) -> exceptions
                .authenticationEntryPoint(
                    new LoginUrlAuthenticationEntryPoint("/login"))
            );
        http.cors().configurationSource(request -> configCors);
        return http.build();
    }

    @Bean
    @Order(2)
    SecurityFilterChain apiFilter(HttpSecurity http) throws Exception {
        http
            .securityMatcher("/api/**")
                .authorizeHttpRequests()
                    .requestMatchers("/api/**").authenticated()
                    .and()
            .oauth2ResourceServer()
                .jwt();
        return http.build();
    }
    
    @Bean 
    @Order(3)
    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http, CorsConfiguration configCors) throws Exception {
        http
            .securityMatcher("/oauth2/**", "/login")
            .authorizeHttpRequests()
                .requestMatchers("/login", "/oauth2/**")
                .authenticated()
                .and()
            .formLogin(Customizer.withDefaults());
        http.cors().configurationSource(request -> configCors);
        return http.build();
    }
    
    @Bean
    public CorsConfiguration corsConfiguration() throws Exception {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowCredentials(true);
        configuration.setAllowedOriginPatterns(List.of("*"));
        configuration.setAllowedMethods(List.of("*"));
        configuration.setAllowedHeaders(List.of("*"));
        return configuration;
    }

如果我尝试在另一个Sping Boot 应用程序中访问另一个Spring API,该应用程序使用第一个作为认证服务器,我没有收到任何错误。非常肯定我的配置有问题...任何提示都将非常感谢!

f4t66c6m

f4t66c6m1#

在最后,结果是配置了另一个过滤器:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class LoopbackIpRedirectFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        if (request.getServerName().equals("localhost") && request.getHeader("host") != null) {
            UriComponents uri = UriComponentsBuilder.fromHttpRequest(new ServletServerHttpRequest(request))
                    .host("127.0.0.1").build();
            response.sendRedirect(uri.toUriString());
            return;
        }
        filterChain.doFilter(request, response);
    }

}

删除 LoopbackIpRedirectFilter 问题已修复

相关问题