Angular 无法在 Spring 使用 Keycloak 启动时获取请求抛出 403

Angular cannot GET request on Spring boot with Keycloak throws 403

我使用 Keycloak 创建了 spring 启动服务。我实现了登录端点。当我通过 Postman 登录服务时,我可以连接到 keycloak 并获取令牌。我可以在其他请求调用中成功使用此令牌。当我使用 angular 登录时,我仍然是令牌,但每次在 spring 启动时请求 returns 403 错误。当我在邮递员中使用相同的令牌时,没有问题。

KeycloakSecurityConfig

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {


 @Value("${server.servlet.context-path}")
 public String contextPath;

 @Override
 protected void configure(HttpSecurity http) throws Exception {
     super.configure(http);
     http.authorizeRequests()
             .antMatchers("/v2/api-docs",
                     "/configuration/ui",
                     "/swagger-resources/**",
                     "/configuration/security",
                     "/swagger-ui.html",
                     "/webjars/**",
                     "/auth/login").permitAll()
             .anyRequest().authenticated()
             .and().cors()
             .and().csrf().disable();
 }


 @Autowired
 public void configureGlobal(AuthenticationManagerBuilder auth) {
     KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
     keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
     auth.authenticationProvider(keycloakAuthenticationProvider);
 }

 @Bean
 @Override
 protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
     return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
 }

 @Bean
 @Override
 protected KeycloakAuthenticationProcessingFilter keycloakAuthenticationProcessingFilter() throws Exception {
     KeycloakAuthenticationProcessingFilter filter = new KeycloakAuthenticationProcessingFilter(this.authenticationManagerBean());
     filter.setSessionAuthenticationStrategy(this.sessionAuthenticationStrategy());
     filter.setAuthenticationFailureHandler(new CustomKeycloakAuthenticationFailureHandler());
     return filter;
 }

 @Bean
 public KeycloakConfigResolver keycloakConfigResolver() {
     return new KeycloakSpringBootConfigResolver();
 }
}

application.yaml

keycloak:
  realm: <realm_name>
  auth-server-url: http://localhost:8287/auth/
  resource: mm-service-1
  credentials:
    secret: bla-bla-bla
  use-resource-role-mappings: false
  cors: true
  bearer-only: true
  enabled: true
  public-client: true

JwtInteceptor

@Injectable()
export class JwtInterceptor implements HttpInterceptor {
    constructor(private accountService: AccountService) {
    }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        // add account header with jwt if user is logged in and request is to the api url
        const user = this.accountService.userValue;
        const isLoggedIn = user && user.token;
        const isApiUrl = request.url.startsWith(Constants.SERVER_BASE_PATH);
        console.log('REQUEST: ', request);
        if (isLoggedIn && isApiUrl) {
            request = request.clone({
                setHeaders: {
                    Authorization: `Bearer ${user.token}`,
                    'withCredentials': `true`,
                    'Access-Control-Allow-Credentials': `true`,
                }
            });
        }
        console.log('NEW REQUEST: ', request);

        return next.handle(request);
    }
}

在 Angular

获取请求
  getListMachine(): void {
    this.machineApi.listMachine(null, null, null, null, null, 'response')
      .pipe(takeUntil(this.unsubscribeAll))
      .subscribe((res: any) => {
        const resHeader = res.headers;
        this.totalRows = resHeader.get('X-Total-Count');
        this.machineInfos = res.body;
      }, (err) => {
        console.error('Err:', err);
      });
  }

Origin Config

@Configuration
public class ApiOriginCorsConfigurer {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry
                        .addMapping("/**")
                        .allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS")
                        .allowedOriginPatterns("*")
                        .exposedHeaders(
                                "Content-Type",
                                "Accept",
                                "Authorization",
                                "link",
                                "content-range",
                                "x-total-count",
                                "location",
                                "etag",
                                "Access-Control-Allow-Origin",
                                "Access-Control-Allow-Credentials")
                        .allowedHeaders("*")
                        .allowCredentials(true)
                ;
            }
        };
    }
}

邮递员请求

Angular请求

如果相同的令牌在邮递员中有效;可能 angular 应用程序有问题。 在 angular

请求中检查您的“授权”header

终于找到问题了。我禁用了 keycloak 的 cors 并且它有效。但是当我想使用cors时,我不知道该怎么做。

如果我是你,我会将这一行 logging.level.org.springframework.security=debug 添加到 application.properties,然后使用 CORS 或不使用它来观察你的应用程序的行为。

希望对你有所帮助。