개발이야기/개념
url path마다 권한 설정
대머리개발자
2024. 7. 9. 10:10
728x90
스프링 시큐리티를 이용하면 쉽게(?) 적용 가능하다.
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN") // Only ADMIN users can access /admin/**
.antMatchers("/user/**").hasAnyRole("ADMIN", "USER") // ADMIN and USER can access /user/**
.anyRequest().authenticated() // Any other req
...
나름 인증서버를 구축해서 사용하기 때문에...비지니스 로직에서 녹여야 한다.
아르메리아 프레임워크를 적용해 인증서버를 구축했기 때문에 쉽게(?) 적용할 수 있다.
@Bean
public ArmeriaServerConfigurator armeriaServerConfigurator() {
return serverBuilder -> {
..
// oauth check
serverBuilder.decorator(AuthService::new);
..
}
}
모든 요청은 이제 AuthService 통과 한다. with 필터!
인그레스 인증을 AuthService 처리 한다.
nginx.ingress.kubernetes.io/auth-url: https://main.domain.co.kr/v2/ingress-oauth
요청에 대한 전체 적인 Flow를 보면
k8s에서 첫번째 관문은 인그레스가 담당한다.
인그레스는 정상적인 요청인지 auth-url을 통해서 확인 하고 라우팅을 한다.
인그레스와 인증 사이의 주고 받는 관계에서 원본 요청의 주소를 아래와 같이 확인 할 수 있다.
request.headers().get("x-auth-request-redirect")
해당 Path 마다 권한을 녹이면 되겠다.
그냥 잘 만들어진 콩게이트웨이는 적용하자. 앞으론 .ㅠ ㅋ ㅠ
비공식적이지만 관리자 콘솔을 통해서 권한을 적용할 수 있더라....
윽 가즈아!!!
create table if not exists `permissionManager`
(
seq BIGINT PRIMARY KEY AUTO_INCREMENT,
path varchar(32) not null,
roleName varchar(100) not null,
`type` varchar(10) default 'exact', // prefix, include
state varchar(2) default 'A' comment 'A:active, D:delete'
);
매칭 Type 은 exact, prefix, include, .. 일단은...
바로 코드로 조져 보자.
@PostConstruct
public void init() {
ServiceUtil.getPermissionManagerService().searchAllByState().subscribe(it -> list.add(it));
}
public static final String TYPE_PREFIX = "prefix";
public static final String TYPE_EXACT = "exact";
public static final String TYPE_INCLUDE = "include";
public static Map<String, PathCheckStrategy> authCheckStrategies = new HashMap<>();
static{
authCheckStrategies.put(TYPE_EXACT, new ExactPathCheckStrategy());
authCheckStrategies.put(TYPE_PREFIX, new PrefixPathCheckStrategy());
authCheckStrategies.put(TYPE_INCLUDE, new IncludePathCheckStrategy());
}
public static Boolean isPermission(String path, List<String> permissions) {
Optional<PermissionManager> authCheck = list.stream().filter((s) -> authCheckStrategies.get(s.getType()).isPathCheck(path, s.getPath())).findFirst();
if(authCheck.isPresent()){
return Arrays.stream(authCheck.get().getRoleName().split(",")).anyMatch( s -> permissions.contains(s));
}else{
return true;
}
}
모든 요청을 체크 해야하는 부담이 된다... 각 EndPoint 하면 안 되나?
일단 비지니스 로직은
1. Permission 적용되지 않는 path는 by Pass
2. Permission 적용 되어 있다면 Role을 체크해서 존재하면 Pass 아니면
if(!URIPermissionManager.isPermission(path, auths)){
throw new AuthorizationException("not.access.authority");
}
그냥 콩게이트 적용하자!!!ㅋㅋㅜ
728x90