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