admin: custom 메뉴 인가 추가
This commit is contained in:
parent
a153536521
commit
44daa3058b
|
|
@ -4,6 +4,9 @@ import com.bpgroup.poc.admin.security.authentication.CustomAuthenticationEntryPo
|
|||
import com.bpgroup.poc.admin.security.authentication.CustomAuthenticationFilter;
|
||||
import com.bpgroup.poc.admin.security.authentication.CustomAuthenticationProvider;
|
||||
import com.bpgroup.poc.admin.security.authentication.service.LoginService;
|
||||
import com.bpgroup.poc.admin.security.authorization.CustomAccessDeniedHandler;
|
||||
import com.bpgroup.poc.admin.security.authorization.CustomAuthorizationManager;
|
||||
import com.bpgroup.poc.admin.security.authorization.service.AuthorizationService;
|
||||
import com.bpgroup.poc.admin.security.jwt.JwtTokenConstants;
|
||||
import com.bpgroup.poc.admin.security.jwt.JwtTokenValidateFilter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
|
@ -35,6 +38,9 @@ public class SecurityConfig {
|
|||
|
||||
private final LoginService loginService;
|
||||
|
||||
private final AuthorizationService authorizationService;
|
||||
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||
|
||||
|
|
@ -48,12 +54,14 @@ public class SecurityConfig {
|
|||
.cacheControl(cache -> cache.disable()) //ERR_CACHE_MISS
|
||||
);
|
||||
|
||||
// 인증 설정
|
||||
// 인가 설정
|
||||
http.authorizeHttpRequests(c -> c
|
||||
.requestMatchers("/css/**", "/images/**", "/js/**", "/font/**", "/favicon.ico").permitAll()
|
||||
.requestMatchers("/common/modal/**").permitAll()
|
||||
.requestMatchers(LOGIN_PATH, LOGOUT_PATH, ERROR_PATH).permitAll()
|
||||
.anyRequest().authenticated());
|
||||
.anyRequest()
|
||||
.access(new CustomAuthorizationManager(authorizationService))
|
||||
);
|
||||
|
||||
http.formLogin(AbstractHttpConfigurer::disable); // Form 로그인이 아닌 Json 로그인으로 분리
|
||||
http.addFilterBefore(authenticationGenerateFilter(), UsernamePasswordAuthenticationFilter.class); // 로그인 관련 Filter 설정
|
||||
|
|
@ -67,6 +75,7 @@ public class SecurityConfig {
|
|||
|
||||
http.exceptionHandling(c -> {
|
||||
c.authenticationEntryPoint(new CustomAuthenticationEntryPoint()); // Authentication 실패 처리
|
||||
c.accessDeniedHandler(new CustomAccessDeniedHandler()); // Authorization 실패 처리
|
||||
});
|
||||
|
||||
http.logout(c -> c
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
package com.bpgroup.poc.admin.security;
|
||||
|
||||
public class SecurityFilterConstants {
|
||||
public static final String[] EXCLUDE_FILTER_STARTS_WITH_URI = {"/login", "/logout", "/error", "/css", "/js", "/images", "/favicon.ico", "/common/modal", "/font"};
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.bpgroup.poc.admin.security.authorization;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.web.access.AccessDeniedHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
|
||||
@Override
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
|
||||
response.sendRedirect("/error?error=" + URLEncoder.encode("메뉴에 접근할 수 있는 권한이 없습니다.", StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.bpgroup.poc.admin.security.authorization;
|
||||
|
||||
import com.bpgroup.poc.admin.security.authorization.service.AuthorizationService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.authorization.AuthorizationDecision;
|
||||
import org.springframework.security.authorization.AuthorizationManager;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class CustomAuthorizationManager implements AuthorizationManager<RequestAuthorizationContext> {
|
||||
|
||||
private final AuthorizationService authorizationService;
|
||||
|
||||
@Override
|
||||
public AuthorizationDecision check(Supplier authentication, RequestAuthorizationContext context) {
|
||||
Authentication auth = (Authentication) authentication.get();
|
||||
|
||||
String userName = (String) auth.getPrincipal();
|
||||
String requestUri = context.getRequest().getRequestURI();
|
||||
|
||||
boolean hasAuthorization = authorizationService.isAuthorized(userName, requestUri);
|
||||
|
||||
return new AuthorizationDecision(hasAuthorization);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.bpgroup.poc.admin.security.authorization.service;
|
||||
|
||||
import com.bpgroup.poc.admin.domain.base.admin.entity.Admin;
|
||||
import com.bpgroup.poc.admin.domain.base.admin.entity.AdminRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional
|
||||
public class AuthorizationService {
|
||||
|
||||
private final AdminRepository adminRepository;
|
||||
|
||||
public boolean isAuthorized(String username, String requestUri) {
|
||||
Optional<Admin> findAdmin = adminRepository.findByLoginId(username);
|
||||
if (findAdmin.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Admin admin = findAdmin.get();
|
||||
return admin.getAdminRole().getRole().getRoleMenus().stream()
|
||||
.anyMatch(roleMenu -> roleMenu.getMenu().getUri().equals(requestUri));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue