사내 전사관리시스템을 개발하는데 있어 엔드포인트 별로 권한설정이 필요했다.
위 사진은 api문서 중 일부다. 엔드포인트 별로 각각의 권한이 설정되어 있음을 알 수 있다.
개요
-> Security에서 권한 설정하는 방법은 크게 2가지다.
문제점
-> 나는 48개 가량 되는 엔드포인트와 권한들을 한눈에 관리하고 싶었다.
따라서, 1번 방법을 채택 후 엔드포인트를 Class로 만들어 관리하기 쉽게 만들었다.
public class EndPoint {
private HttpMethod method;
// Method 방식
private String endPointName;
// endpotint 이름
private Role[] roles;
// 권한들
public static EndPoint of(HttpMethod method, String endPointName) {
EndPoint endPoint = new EndPoint();
endPoint.method = method;
endPoint.endPointName = endPointName;
endPoint.roles = new Role[]{Role.ROLE_LV1,Role.ROLE_LV2,Role.ROLE_LV3,Role.ROLE_LV4};
return endPoint;
}
public static EndPoint of(HttpMethod method, String endPointName,Role ...role) {
EndPoint endPoint = new EndPoint();
endPoint.method = method;
endPoint.endPointName = endPointName;
endPoint.roles = role;
return endPoint;
}
public String[] getRoles() {
return Arrays.stream(roles)
.map(Enum::toString)
.toArray(String[]::new);
}
}
public enum EndPointAccessByLevel {
ROLES(List.of(
//----------- day-off ------------------
EndPoint.of(GET,"/api/v1/day-off/remaining",ROLE_LV1,ROLE_LV2),
EndPoint.of(GET,"/api/v1/day-off/excell",ROLE_LV2,ROLE_LV3,ROLE_LV4),
EndPoint.of(PUT,"/api/v1/day-off",ROLE_LV1,ROLE_LV2),
EndPoint.of(POST,"/api/v1/day-off",ROLE_LV1,ROLE_LV2),
//----------- day-off ------------------
...
)),
COMMON(List.of(
//----------- Day-off ------------------
EndPoint.of(GET,"/api/v1/day-off"),
EndPoint.of(GET,"/api/v1/day-off/**"),
//----------- Day-off ------------------
...
)),
NONE(List.of(
//--------------login-------------------------
EndPoint.of(POST,"/api/v1/login"),
//--------------login-------------------------
...
));
private final List<EndPoint> endPoints;
EndPointAccessByLevel(List<EndPoint> endPointList) {
endPoints = endPointList;
}
public List<EndPoint> getEndPoints() {
return endPoints;
}
}
private void authorizeRequests(HttpSecurity http) throws Exception {
EndPointAccessByLevel.NONE.getEndPoints()
.forEach(endPoint -> {
try {
http.authorizeRequests()
.antMatchers(endPoint.getMethod(), endPoint.getEndPointName()).permitAll();
} catch (Exception e) {
throw new RuntimeException(e);
}
});
EndPointAccessByLevel.ROLES.getEndPoints()
.forEach(endPoint -> {
try {
http.authorizeRequests()
.antMatchers(endPoint.getMethod(), endPoint.getEndPointName()).hasAnyAuthority(endPoint.getRoles());
} catch (Exception e) {
throw new RuntimeException(e);
}
});
EndPointAccessByLevel.COMMON.getEndPoints()
.forEach(endPoint -> {
try {
http.authorizeRequests()
.antMatchers(endPoint.getMethod(), endPoint.getEndPointName()).hasAnyAuthority(endPoint.getRoles());
} catch (Exception e) {
throw new RuntimeException(e);
}
});
http.authorizeRequests().anyRequest().authenticated();// 그 외 항목 전부 인증 적용
}