Login Servicesの追加[3]Gateway認証
前の記事までにloginトークンを配布しました.これで、ログイン後に他のサービスを使用する場合、Gatewayでトークン値の処理を試み、有効かどうかを確認してから操作を続行します.
🔨任意のサービスの作成
🔨任意のサービスの作成 login-servie
では、自身がフィルタでフィルタリングされているため、ゲートウェイで正しくフィルタリングされていることを確認するために、order-service
が生成されるので、ランダムにサービスが作成され、追加される.
👉サービスの作成
選択したオプションは次のとおりです.server:
port: 0
spring:
application:
name: order-service
eureka:
instance:
instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}}
設定情報を入力します.
configサーバに登録してconfigを使用していない場合はgradleでconfigを注釈して使用します.
@SpringBootApplication
@EnableDiscoveryClient
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
Eurekaで見つけられるように設定@RestController
@RequestMapping("/")
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello Order Service!";
}
}
リクエストを
👉ゲートウェイ設定の変更
server:
port: 8000
eureka:
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://127.0.0.1:8761/eureka
# token 추가해줘야함!!!!
token:
expiration_time: 86400000 #ms단위
secret: 토큰 값
spring:
application: #gateway service 이름름
name: gateway-service
cloud:
gateway: #gateway 설정
routes:
# login service
- id: login-service
uri: lb://LOGIN-SERVICE
predicates:
- Path=/login-service/**
- Method=GET, POST
filters:
- RemoveRequestHeader=Cookie
- RewritePath=/login-service(?<segment>.*), /$\{segment}
# order service
- id: order-service
uri: lb://ORDER-SERVICE
predicates:
- Path=/order-service/**
- Method=GET, POST
filters:
- RemoveRequestHeader=Cookie
- RewritePath=/order-service(?<segment>.*), /$\{segment}
gateway.yml
ファイルの内容を次のように設定します.orderサービスが追加されました.
その後、テストを行い、トークン値がなくても正常に処理できることを確認できます.今修正して、コインがなければ処理できません.
🔨ゲートウェイ設定の変更 implementation 'io.jsonwebtoken:jjwt:0.9.1'
implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1'
2つの依存項目を追加します.@Component
@Slf4j
@RequiredArgsConstructor
public class AuthFilter extends AbstractGatewayFilterFactory<AuthFilter.Config> {
private final Environment env;
public static class Config{
//설정에 필요한 내용 정의
}
//인증 요청시 확인
@Override
public GatewayFilter apply(Config config) {
return ((exchange, chain)->{
ServerHttpRequest request = exchange.getRequest();
if(!request.getHeaders().containsKey(HttpHeaders.AUTHORIZATION)){
//헤더에 AUTHORIZATION key 자체가 존재하지 않을 경우
return onError(exchange, "no AUTHORIZATION header", HttpStatus.UNAUTHORIZED); //401 반환
}
String authorizationHeader = request.getHeaders().get(org.springframework.http.HttpHeaders.AUTHORIZATION).get(0); //AUTHORIZATION key 값으로 value 가져옴
String jwt = authorizationHeader.replace("Bearer", ""); //JWT, OAuth는 Bearer로 붙여서 전송하기로 약속함
if(!isJwtValid(jwt)){
return onError(exchange, "JWT Token is not valid", HttpStatus.UNAUTHORIZED);
}
return chain.filter(exchange);
});
}
//token이 유효한지 확인
private boolean isJwtValid(String jwt) {
boolean returnValue = true;
String subject = null;
try {
subject = Jwts.parser().setSigningKey(env.getProperty("token.secret")) //secret key 값을 통해 parse
.parseClaimsJws(jwt).getBody() //token의 내용을 가져옴
.getSubject();
}catch (Exception e){
returnValue = false;
}
if(subject == null || subject.equals("")){
returnValue = false;
}
return returnValue;
}
//에러 발생시 에러 값을 response
//Mono, Flux -> Spring WebFlux 개념 / 데이터 단위 단일=Mono, 복수=Flux
private Mono<Void> onError(ServerWebExchange exchange, String err, HttpStatus httpStatus) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(httpStatus);
log.error(err);
return response.setComplete(); //Mono 데이터 return
}
}
フィルタを追加しましょうfilterの内容はlogin-service
の認証とほぼ同じですが、WebFluxのMonとServer Httpを使用しています.まだ内容を深く見ていないので、よくわかりませんが、必ず勉強しなければならない部分です!
🔨gatewayプロファイルの変更 server:
port: 8000
eureka:
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://127.0.0.1:8761/eureka
token:
expiration_time: 86400000 #ms단위
secret: 토큰 값
spring:
application: #gateway service 이름름
name: gateway-service
cloud:
gateway: #gateway 설정
routes:
# login service
- id: login-service
uri: lb://LOGIN-SERVICE
predicates:
- Path=/login-service/**
- Method=GET, POST
filters:
- RemoveRequestHeader=Cookie
- RewritePath=/login-service(?<segment>.*), /$\{segment}
# order service
- id: order-service
uri: lb://ORDER-SERVICE
predicates:
- Path=/order-service/**
- Method=GET, POST
filters:
- RemoveRequestHeader=Cookie
- RewritePath=/order-service(?<segment>.*), /$\{segment}
- AuthFilter #토큰 처리 필터 적용
最終的に、ゲートウェイのプロファイルは次のように変更する必要があります.
👊テスト
では、今401で返します.
gatewayは私たちが設定したエラーメッセージを出力します.
会員加入後
登録後に発行されるコイン
適用後、正常に戻ることを確認できます!
Reference
この問題について(Login Servicesの追加[3]Gateway認証), 我々は、より多くの情報をここで見つけました
https://velog.io/@ililil9482/Login-Service3-gateway-인증-추가
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
server:
port: 0
spring:
application:
name: order-service
eureka:
instance:
instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}}
@SpringBootApplication
@EnableDiscoveryClient
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
@RestController
@RequestMapping("/")
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello Order Service!";
}
}
server:
port: 8000
eureka:
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://127.0.0.1:8761/eureka
# token 추가해줘야함!!!!
token:
expiration_time: 86400000 #ms단위
secret: 토큰 값
spring:
application: #gateway service 이름름
name: gateway-service
cloud:
gateway: #gateway 설정
routes:
# login service
- id: login-service
uri: lb://LOGIN-SERVICE
predicates:
- Path=/login-service/**
- Method=GET, POST
filters:
- RemoveRequestHeader=Cookie
- RewritePath=/login-service(?<segment>.*), /$\{segment}
# order service
- id: order-service
uri: lb://ORDER-SERVICE
predicates:
- Path=/order-service/**
- Method=GET, POST
filters:
- RemoveRequestHeader=Cookie
- RewritePath=/order-service(?<segment>.*), /$\{segment}
implementation 'io.jsonwebtoken:jjwt:0.9.1'
implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.1'
2つの依存項目を追加します.@Component
@Slf4j
@RequiredArgsConstructor
public class AuthFilter extends AbstractGatewayFilterFactory<AuthFilter.Config> {
private final Environment env;
public static class Config{
//설정에 필요한 내용 정의
}
//인증 요청시 확인
@Override
public GatewayFilter apply(Config config) {
return ((exchange, chain)->{
ServerHttpRequest request = exchange.getRequest();
if(!request.getHeaders().containsKey(HttpHeaders.AUTHORIZATION)){
//헤더에 AUTHORIZATION key 자체가 존재하지 않을 경우
return onError(exchange, "no AUTHORIZATION header", HttpStatus.UNAUTHORIZED); //401 반환
}
String authorizationHeader = request.getHeaders().get(org.springframework.http.HttpHeaders.AUTHORIZATION).get(0); //AUTHORIZATION key 값으로 value 가져옴
String jwt = authorizationHeader.replace("Bearer", ""); //JWT, OAuth는 Bearer로 붙여서 전송하기로 약속함
if(!isJwtValid(jwt)){
return onError(exchange, "JWT Token is not valid", HttpStatus.UNAUTHORIZED);
}
return chain.filter(exchange);
});
}
//token이 유효한지 확인
private boolean isJwtValid(String jwt) {
boolean returnValue = true;
String subject = null;
try {
subject = Jwts.parser().setSigningKey(env.getProperty("token.secret")) //secret key 값을 통해 parse
.parseClaimsJws(jwt).getBody() //token의 내용을 가져옴
.getSubject();
}catch (Exception e){
returnValue = false;
}
if(subject == null || subject.equals("")){
returnValue = false;
}
return returnValue;
}
//에러 발생시 에러 값을 response
//Mono, Flux -> Spring WebFlux 개념 / 데이터 단위 단일=Mono, 복수=Flux
private Mono<Void> onError(ServerWebExchange exchange, String err, HttpStatus httpStatus) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(httpStatus);
log.error(err);
return response.setComplete(); //Mono 데이터 return
}
}
フィルタを追加しましょうfilterの内容はlogin-service
の認証とほぼ同じですが、WebFluxのMonとServer Httpを使用しています.まだ内容を深く見ていないので、よくわかりませんが、必ず勉強しなければならない部分です!🔨gatewayプロファイルの変更 server:
port: 8000
eureka:
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://127.0.0.1:8761/eureka
token:
expiration_time: 86400000 #ms단위
secret: 토큰 값
spring:
application: #gateway service 이름름
name: gateway-service
cloud:
gateway: #gateway 설정
routes:
# login service
- id: login-service
uri: lb://LOGIN-SERVICE
predicates:
- Path=/login-service/**
- Method=GET, POST
filters:
- RemoveRequestHeader=Cookie
- RewritePath=/login-service(?<segment>.*), /$\{segment}
# order service
- id: order-service
uri: lb://ORDER-SERVICE
predicates:
- Path=/order-service/**
- Method=GET, POST
filters:
- RemoveRequestHeader=Cookie
- RewritePath=/order-service(?<segment>.*), /$\{segment}
- AuthFilter #토큰 처리 필터 적용
最終的に、ゲートウェイのプロファイルは次のように変更する必要があります.
👊テスト
では、今401で返します.
gatewayは私たちが設定したエラーメッセージを出力します.
会員加入後
登録後に発行されるコイン
適用後、正常に戻ることを確認できます!
Reference
この問題について(Login Servicesの追加[3]Gateway認証), 我々は、より多くの情報をここで見つけました
https://velog.io/@ililil9482/Login-Service3-gateway-인증-추가
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
server:
port: 8000
eureka:
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://127.0.0.1:8761/eureka
token:
expiration_time: 86400000 #ms단위
secret: 토큰 값
spring:
application: #gateway service 이름름
name: gateway-service
cloud:
gateway: #gateway 설정
routes:
# login service
- id: login-service
uri: lb://LOGIN-SERVICE
predicates:
- Path=/login-service/**
- Method=GET, POST
filters:
- RemoveRequestHeader=Cookie
- RewritePath=/login-service(?<segment>.*), /$\{segment}
# order service
- id: order-service
uri: lb://ORDER-SERVICE
predicates:
- Path=/order-service/**
- Method=GET, POST
filters:
- RemoveRequestHeader=Cookie
- RewritePath=/order-service(?<segment>.*), /$\{segment}
- AuthFilter #토큰 처리 필터 적용
では、今401で返します.
gatewayは私たちが設定したエラーメッセージを出力します.
会員加入後
登録後に発行されるコイン
適用後、正常に戻ることを確認できます!
Reference
この問題について(Login Servicesの追加[3]Gateway認証), 我々は、より多くの情報をここで見つけました https://velog.io/@ililil9482/Login-Service3-gateway-인증-추가テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol