I am facing the OAuth issue, details are below: I am having two microservices: registration-service(https://github.com/choudharylakshyaveer/registration-service) student-service(https://github.com/choudharylakshyaveer/student-service)
For these two I have added : cloud-config-server(https://github.com/choudharylakshyaveer/cloud-config-server) naminig-server(https://github.com/choudharylakshyaveer/naming-server) gateway(https://github.com/choudharylakshyaveer/api-gateway)
FrontEnd: is at react js: https://github.com/choudharylakshyaveer/chargie
For first time use, a new user need to be register that can be done from curl:
curl --location --request GET 'http://localhost:8765/user/save' --header 'Content-Type: application/json' --data-raw '{ "username": "user@chargie.com", "password": "chaudhary22", "enabled": true, "roles": [ "ROLE_ADMIN", "ROLE_USER" ] }'
To login using the above registered user, below can be run from cUrl:
curl --location --request POST 'http://localhost:8765/login' --header 'Content-Type: application/json' --data-raw '{ "username": "user@chargie.com", "password": "chaudhary22" }'
Once I log In and get the Bearer token, after that I am facing cors issue from the reactJs FE, bu same request is working fine from the Postman, below is request from postman:
curl --location --request GET 'http://localhost:8765/REGISTRATION-SERVICE/test' --header 'Access-Control-Allow-Credentials: true' --header 'Access-Control-Allow-Headers: content-type' --header 'Access-Control-Allow-Methods: PUT, POST, GET, DELETE, PATCH, OPTIONS' --header 'Access-Control-Allow-Origin: *' --header 'Access-Control-Max-Age: 1800' --header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJyb2xlIjpbIlJPTEVfQURNSU4iLCJST0xFX1VTRVIiXSwic3ViIjoibHZzIiwiaWF0IjoxNjU4OTM0NzIxLCJleHAiOjE2NTg5NjM1MjF9.MN6lCrwLB2bBDBLp-HG4nlSRlyhoR2cQDSRGvJCD2WwDMojhei0wW7xVuDwVCtRUANK02aQMhqagafB2csDWWg'
Below is the code used to hit request from ReactJs FE:
var config = { method: 'get', url: 'http://localhost:8765/REGISTRATION-SERVICE/test', headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true', 'Access-Control-Max-Age': '1800', 'Access-Control-Allow-Headers': 'content-type', 'Access-Control-Allow-Methods': 'PUT, POST, GET, DELETE, PATCH, OPTIONS' }, Authorization: `Bearer ${token}` }; axios(config) .then(function (response) { console.log(JSON.stringify(response.data)); }) .catch(function (error) { console.log(error); });
And this request gives me CORS issue:
Snippet of the ServerSecurityContextRepository’s overridden method used in SecurityContextRepository class of api-gateway:
@Override public Mono<SecurityContext> load(ServerWebExchange swe) { ServerHttpRequest request = swe.getRequest(); HttpHeaders headers = request.getHeaders(); String authHeader = headers.getFirst(HttpHeaders.AUTHORIZATION); if (authHeader != null && authHeader.startsWith("Bearer ")) { String authToken = authHeader.substring(7); Authentication auth = new UsernamePasswordAuthenticationToken(authToken, authToken); return this.authenticationManager.authenticate(auth).map((authentication) -> { return new SecurityContextImpl(authentication); }); } else { return Mono.empty(); } }
Here when the request is coming from the Postman then below is receievd in the headers
variable:
[access-control-allow-credentials:"true", access-control-allow-headers:"content-type", access-control-allow-methods:"PUT, POST, GET, DELETE, PATCH, OPTIONS", access-control-allow-origin:"*", access-control-max-age:"1800", authorization:"Bearer eyJhbGciOiJIUzUxMiJ9.eyJyb2xlIjpbIlJPTEVfQURNSU4iLCJST0xFX1VTRVIiXSwic3ViIjoibHZzIiwiaWF0IjoxNjU4OTM0NzIxLCJleHAiOjE2NTg5NjM1MjF9.MN6lCrwLB2bBDBLp-HG4nlSRlyhoR2cQDSRGvJCD2WwDMojhei0wW7xVuDwVCtRUANK02aQMhqagafB2csDWWg", user-agent:"PostmanRuntime/7.29.0", accept:"*/*", postman-token:"6c0d7a9a-dcde-45d7-8422-1476682db9f4", host:"localhost:8765", accept-encoding:"gzip, deflate, br", connection:"keep-alive"]
But when same request comes from Front end then below is receievd in the headers
variable and it seems to be malformed:
[host:"localhost:8765", connection:"keep-alive", pragma:"no-cache", cache-control:"no-cache", accept:"*/*", access-control-request-method:"GET", access-control-request-headers:"access-control-allow-credentials,access-control-allow-headers,access-control-allow-methods,access-control-allow-origin,access-control-max-age,authorization", origin:"http://localhost:3000", user-agent:"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36", sec-fetch-mode:"cors", sec-fetch-site:"same-site", sec-fetch-dest:"empty", referer:"http://localhost:3000/", accept-encoding:"gzip, deflate, br", accept-language:"en-US,en;q=0.9"]
So, Here I am not receiving proper Authorization header on backend’s headers variable so that I can take Bearer token to validate it.
Advertisement
Answer
Working after adding cors, complete code below for SecurityWebFilterChain’s method :
http .exceptionHandling() .authenticationEntryPoint((swe, e) -> { return Mono.fromRunnable(() -> { swe.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); }); }).accessDeniedHandler((swe, e) -> { return Mono.fromRunnable(() -> { swe.getResponse().setStatusCode(HttpStatus.FORBIDDEN); }); }).and() .cors().configurationSource(request -> { CorsConfiguration config = new CorsConfiguration(); config.setAllowedOrigins(Collections.singletonList("*")); config.setAllowedMethods(Arrays.asList("GET","POST","PUT","PATCH", "DELETE","OPTIONS")); config.setAllowedHeaders(Collections.singletonList("*")); return config; }) .and() .csrf().disable() .and() .formLogin().disable() .httpBasic().disable() .authenticationManager(authenticationManager) .securityContextRepository(securityContextRepository) .authorizeExchange() .pathMatchers("/login").permitAll() .pathMatchers("/user/save").permitAll() //line added .anyExchange() .authenticated() .and().build();