2021.10.23 - [IT 기술/권한 인증&인가] - [Spring Security] Authentication 라이브러리 구현
8. AuthorizationChecker.java
ignore, permitAll처리 되지 않은 모든 url 요청이 들어오면 AuthorizationChecker를 통해 메뉴 또는 api에 대한 권한 체크를 한다.
해당 url이 메뉴이면 권한그룹 AuthGroup을 체크하고, api이면 역할 AuthRole을 체크한다.
@Component("sufinnAuthorizationChecker")
@RequiredArgsConstructor
public class AuthorizationChecker {
@Value("${security.login.success.redirect-uri}")
private String loginSuccessRedirect;
private final AuthCacheManager authCacheManager;
private final AuthUserService authUserService;
private final AntPathMatcher matcher = new AntPathMatcher();
public boolean check(HttpServletRequest request, Authentication authentication) {
String uri = request.getRequestURI();
String method = request.getMethod().toUpperCase();
Object principalObj = authentication.getPrincipal();
// 로그인 Authentication 확인
if (!(principalObj instanceof User)) {
return false;
}
CustomUserDetails customUserDetails = (CustomUserDetails) authentication.getPrincipal();
// 인증여부 확인
if(ObjectUtils.isEmpty(customUserDetails.getUser()))
{
return false;
}
if(uri.equals(loginSuccessRedirect))
{
return true;
}
// url 권한 확인 ============================================================
List<Integer> authGroupSeqs = new ArrayList<Integer>(); // 보유 권한그룹
List<String> allRole = new ArrayList<String>(); // 보유한 모든 role (하위 포함)
this.setAllAuthority(authGroupSeqs, allRole, customUserDetails.getAuthorities());
// 메뉴에서 체크
List<Integer> menuEle = authCacheManager.getCacheUserGroupMenu(uri);
if(!ObjectUtils.isEmpty(menuEle))
{
for (Integer authGroup : authGroupSeqs) {
return menuEle.contains(authGroup);
}
return false;
}
// api에서 체크
List<String> apiKeys = authCacheManager.getRoleApiKeys();
String path = String.format("%s%s", method,uri);
for (String key : apiKeys) {
if(matcher.match(key, path))
{
return allRole.contains(authCacheManager.getCacheRoleApi(key));
}
}
return true;
}
private void setAllAuthority(List<Integer> authGroupSeqs, List<String> allRole, Collection<GrantedAuthority> collection)
{
for (GrantedAuthority authority : collection) {
UserGrantedAuthority userAuthority = (UserGrantedAuthority) authority;
authGroupSeqs.add(userAuthority.getAuthGroup().getId());
this.setChildRoles(allRole, userAuthority.getAuthGroup());
}
}
private void setChildRoles(List<String> roleList, AuthGroup authGroup)
{
// role id
for(AuthRole ar : authGroup.getAuthRoleList())
{
if(!roleList.contains(ar.getId()))
{
roleList.add(ar.getId());
}
}
if(authGroup.hasChlid())
{
for (AuthGroup cAg : authGroup.getChlidAuthGroupList()) {
this.setChildRoles(roleList, cAg);
}
}
}
}
9. 권한이 없는 사용자 접근시 처리
9-1. HttpAuthenticationEntryPoint.java
spring-security의 AuthenticationEntryPoint 인터페이스를 따른다.
로그인 권한이 없는 경우 spring-security 필터체인은 이곳을 태워 사용자에게 401 응답한다.
public class HttpAuthenticationEntryPoint implements AuthenticationEntryPoint{
@Autowired
private MessageProvider messageProvider;
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, messageProvider.getMessage(AuthConstants.MSG_ERROR_AUTH_FAIL));
}
}
9-1. HttpAccessDeniedHandler.java
spring-security의 AccessDeniedHandler 인터페이스를 따른다.
권한이 없는 요청을 한 경우 spring-security 필터체인은 이곳을 태워 사용자에게 403 응답한다.
public class HttpAccessDeniedHandler implements AccessDeniedHandler{
@Autowired
private MessageProvider messageProvider;
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_FORBIDDEN, messageProvider.getMessage(AuthConstants.MSG_ERROR_PERMISSION_DENIED));
}
}
'기술 > Spring Security' 카테고리의 다른 글
[Spring Security] 로그인 기능 구현 (0) | 2021.10.24 |
---|---|
[Spring security] Authentication 라이브러리 구현 (0) | 2021.10.23 |
[Spring] Spring Security란? (3) | 2021.07.11 |