[英]OAuth issue in API gateway
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 -服務)
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 )
前端:在反應 js: https://github.com/choudharylakshyaveer/chargie
第一次使用,需要注冊一個新用戶,可以從 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"
]
}'
要使用上述注冊用戶登錄,可以從 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'
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);
});
api-gateway 的 SecurityContextRepository class 中使用的 ServerSecurityContextRepository 的重寫方法的片段:
@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();
}
}
在這里,當請求來自 Postman 時,下面是headers
變量中的接收:
[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"]
但是當相同的請求來自前端時,下面會在headers
變量中收到,並且它似乎格式不正確:
[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"]
因此,在這里我沒有在后端的headers變量上收到正確的授權 header,以便我可以使用 Bearer 令牌來驗證它。
添加cors后工作,SecurityWebFilterChain方法的完整代碼如下:
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();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.