320x100
반응형
사용자가 크게 멘토와 멘티 두개의 역할 군으로 나뉘어져 있고 두 역할이 하나의 API Endpoint를 공유해서 사용을 하고 있고 하나의 값에 대해서 접근 권한이 다르기 때문에 분기 처리가 필요로 하고 사전에 filter에서 처리된 Role을 가져오고자 한다
반응형
Annotation
Role을 가져오기 위해서는 SecurityContext에 접근을 해야 하는데 Security에서 제공하는 것으로는 @AuthenticationPrincipal
, @CurrentSecurityContext
가 있다
@AuthenticationPrincipal
- SecurityContext에 담겨진 Authentication에서
getPrincipal()
을 통해 principal 객체를 반환 @CurrentSecurityContext
추가로 Expression(SpEL 식)을 통해서 SecurityContext 내부에 필요한 것을 가져올 수 있다- 위 어노테이션은 특정 내부에 있는 객체를 반환하지만 해당 어노테이션은 SecurityContext 자체를 반환해준다
작동원리
작동 원리자체는 단순하다 ArgumentResolver에 의해서 값을 바인딩해준다
@Override
public boolean supportsParameter(MethodParameter parameter) {
return findMethodAnnotation(CurrentSecurityContext.class, parameter) != null;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
SecurityContext securityContext = this.securityContextHolderStrategy.getContext();
if (securityContext == null) {
return null;
}
Object securityContextResult = securityContext;
CurrentSecurityContext annotation = findMethodAnnotation(CurrentSecurityContext.class, parameter);
String expressionToParse = annotation.expression();
if (StringUtils.hasLength(expressionToParse)) {
StandardEvaluationContext context = new StandardEvaluationContext();
context.setRootObject(securityContext);
context.setVariable("this", securityContext);
context.setBeanResolver(this.beanResolver);
Expression expression = this.parser.parseExpression(expressionToParse);
securityContextResult = expression.getValue(context);
}
if (securityContextResult != null
&& !parameter.getParameterType().isAssignableFrom(securityContextResult.getClass())) {
if (annotation.errorOnInvalidType()) {
throw new ClassCastException(
securityContextResult + " is not assignable to " + parameter.getParameterType());
}
return null;
}
return securityContextResult;
}
320x100
사용 방법
@GetMapping("/{eventId}")
public EventResponse getAllAttendResumes(@PathVariable Long eventId, @CurrentSecurityContext(expression = "authentication") Authentication auth) {
Event event = eventService.getOne(eventId);
List<EventPosition> positions = eventPositionService.getAll(eventId);
if (isMentor(auth)) {
return new EventResponse(event, positions, getResumes(event));
}
return new EventResponse(event, positions, List.of());
}
private boolean isMentor(Authentication auth) {
return auth.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.anyMatch(authority -> authority.equals("ROLE_MENTOR"));
}
참고
Guide to @CurrentSecurityContext in Spring Security | Baeldung
320x100
반응형
'공부기록 > Spring Security' 카테고리의 다른 글
Spring Security - 동적 권한 처리 (2) | 2023.03.29 |
---|---|
[추가] 스프링 시큐리티 OAuth 로그인 처리 방법 2 (0) | 2023.02.22 |
[추가] 스프링 시큐리티 OAuth 로그인 처리 방법 1 (2) | 2023.02.22 |
[실습] 스프링 시큐리티 OAuth2 Login 2 (2) | 2023.02.21 |
[실습] 스프링 시큐리티 OAuth2 Login 1 (0) | 2023.02.21 |