Home > Software design >  Angular cannot GET request on Spring boot with Keycloak throws 403
Angular cannot GET request on Spring boot with Keycloak throws 403

Time:03-09

I created spring boot service using with Keycloak. And I implemented login end-point. When I logged in the service over Postman, I can connect to keycloak and take token. And I can use this token on other request calls succesfully. When I logged in it with angular I still the token but request returns 403 error every time in spring boot. When I use the same token in postman, there is no problem.

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);
    }
}

Get request on 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)
                ;
            }
        };
    }
}

Postman request enter image description here

Angular Request

enter image description here

enter image description here

CodePudding user response:

Finally, I found problem. I disabled cors of the keycloak and it works. But When I want to use cors, I don't know what to do.

CodePudding user response:

If the same token works in postman; probably angular application is the problem. Check your "Authorization" header in request with angular

  • Related