Map 기반 방식의 DB 연동방법
필요한 클래스는 UrlResourceMapFactoryBean이다. (FactoryBean 구현)
- DB에서 얻은 권한/자원 정보를 ResourceMap 빈으로 생성하여 UrlFilterInvocationSecurityMetadataSource 에 전달한다
구현
자원, 권한 정보를 넘겨줄 클래스는 FactoryBean 을 구현한다.
제네릭으로 <LinkedHashMap<RequestMatcher, List<ConfigArribute>> 를 선언한다.
- DB에서 가져올 권한/ 자원 정보를 가져올 Service를 필드로 선언
- LinkedHashMap<RequestMatcher, List<ConfigAttribute>> 를 필드로 선언
- getObject() : Map에 정보가 없다면 init() 실행, 있다면 Map을 리턴
- init() : Service 에서 DB와 커넥트하여 권한과 자원 정보의 매핑 정보를 Map에 저장
- isSington() : 싱글톤 여부
- getObjectType() : LinkedHashMap
public class UrlResourcesMapFactoryBean implements FactoryBean<LinkedHashMap<RequestMatcher, List<ConfigAttribute>>> {
private SecurityResourceService securityResourceService;
private LinkedHashMap<RequestMatcher, List<ConfigAttribute>> resourceMap;
public void setSecurityResourceService(SecurityResourceService securityResourceService) {
this.securityResourceService = securityResourceService;
}
@Override
public LinkedHashMap<RequestMatcher, List<ConfigAttribute>> getObject() throws Exception {
if(resourceMap == null){
init();
}
return resourceMap;
}
private void init() {
resourceMap = securityResourceService.getResourceList();
}
@Override
public Class<?> getObjectType() {
return LinkedHashMap.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
DB 에서 권한, 자원정보를 넘겨줄 Service
- Service 필드 선언
- Getter로 LinkedHashMap을 넘김
- 반복을 돌며 키( RequestMatcher ) , 값 ( SecurityConfig ) 을 매핑하여 리턴
- 권한과 자원은 N:M 관계이므로 중간 테이블로 관계를 1:N 관계로 풀어주어야 함
@Service
public class SecurityResourceService {
private ResourcesRepository resourcesRepository;
public SecurityResourceService(ResourcesRepository resourcesRepository) {
this.resourcesRepository = resourcesRepository;
}
public LinkedHashMap<RequestMatcher, List<ConfigAttribute>> getResourceList(){
LinkedHashMap<RequestMatcher, List<ConfigAttribute>> result = new LinkedHashMap<>();
List<Resources> resourcesList = resourcesRepository.findAllResources();
resourcesList.forEach(re ->{
List<ConfigAttribute> configAttributeList = new ArrayList<>();
re.getRoleSet().forEach(role -> {
configAttributeList.add(new SecurityConfig(role.getRoleName()));
});
result.put(new AntPathRequestMatcher(re.getResourceName()),configAttributeList);
});
return result;
}
}
SecurityConfig 클래스
- CustomFactoryBean 을 생성하여 주입받은 Service를 준다.
- CustomFilterInvocationSecurityMetadataSource 클래스의 생성자로 FactoryBean 의 Map을 넘긴다.
@Bean
public UrlFilterInvocationSecurityMetadataSource urlFilterInvocationSecurityMetadataSource() throws Exception {
return new UrlFilterInvocationSecurityMetadataSource(urlResourcesMapFactoryBean().getObject(), securityResourceService);
}
private UrlResourcesMapFactoryBean urlResourcesMapFactoryBean() {
UrlResourcesMapFactoryBean urlResourcesMapFactoryBean = new UrlResourcesMapFactoryBean();
urlResourcesMapFactoryBean.setSecurityResourceService(securityResourceService);
return urlResourcesMapFactoryBean;
}
'springframework > 시작하자SpringSecurity' 카테고리의 다른 글
39.FilterInvocationSecurityMetadataSource (1) (0) | 2020.09.30 |
---|---|
38.인가프로세스의 아키텍쳐 (0) | 2020.09.30 |
37. 동적 인가 방식 개요 (0) | 2020.09.30 |
39.Ajax 로그인 구현, CSRF (0) | 2020.09.30 |
38.AjaxLoginUrlAuthenticationEntryPoint, AjaxAccessDeniedHandler (0) | 2020.09.30 |