이 시리즈에 나오는 모든 내용은 인프런 인터넷 강의 - 스프링 시큐리티 - Spring Boot 기반으로 개발하는 Spring Security - 에서 기반된 것입니다. 그리고 여기서 인용되는 PPT 이미지 또한 모두 해당 강의에서 가져왔음을 알립니다. 추가적으로 여기에 작성된 코드들 또한 해당 강의의 github 에 올라와 있는 코드를 참고해서 만든 겁니다.
import lombok.*;
import javax.persistence.*;
import java.io.Serializable;
@Entity
@Data
@Table(schema = "public", name = "ACCESS_IP")
@EqualsAndHashCode(of = "id")
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AccessIp implements Serializable {
@Id
@GeneratedValue
@Column(name = "IP_ID")
private Long id;
@Column(name = "IP_ADDRESS", nullable = false)
private String ipAddress;
}
import io.security.corespringsecurity.domain.entity.AccessIp;
import org.springframework.data.jpa.repository.JpaRepository;
public interface AccessIpRepository extends JpaRepository<AccessIp, Long> {
AccessIp findByIpAddress(String ipAddress);
}
서버 한번 실행해서 자동 DDL 되도록한 후, 테이블에 직접 insert 해주자.
INSERT INTO public.access_ip
(ip_id, ip_address)
VALUES(0, '0:0:0:0:0:0:0:1');
import io.security.corespringsecurity.security.service.SecurityResourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import java.util.Collection;
import java.util.List;
public class IpAddressVoter implements AccessDecisionVoter<Object> {
@Autowired
private SecurityResourceService securityResourceService;
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}
@Override
public boolean supports(Class<?> clazz) {
return true;
}
@Override
public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
WebAuthenticationDetails details = (WebAuthenticationDetails) authentication.getDetails();
String remoteAddress = details.getRemoteAddress();
List<String> accessIpList = securityResourceService.getAccessIpList();
int result = ACCESS_DENIED;
if (accessIpList.contains(remoteAddress)) {
return ACCESS_ABSTAIN;
}
throw new AccessDeniedException("Invalid IP Address");
}
}
이 Voter 를 이제 Spring Security 설정에 적용해주면 끝이다.
@Configuration
@EnableWebSecurity
@Slf4j
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 1. 빈 등록!
@Bean
public IpAddressVoter ipAddressVoter() {
return new IpAddressVoter();
}
@Bean
public AccessDecisionVoter<? extends Object> roleVoter() {
RoleHierarchyVoter roleHierarchyVoter = new RoleHierarchyVoter(roleHierarchy());
return roleHierarchyVoter;
}
@Bean
public RoleHierarchyImpl roleHierarchy() {
return new RoleHierarchyImpl();
}
private List<AccessDecisionVoter<?>> getAccessDecistionVoters() {
List<AccessDecisionVoter<? extends Object>> accessDecisionVoters = new ArrayList<>();
// 2. 가장 먼저 IP가 심사가되도록 해야한다.
accessDecisionVoters.add(ipAddressVoter());
accessDecisionVoters.add(roleVoter());
return accessDecisionVoters;
}
// AccessDecisionManager 에 최종 적용
private AccessDecisionManager affirmativeBased() {
AffirmativeBased affirmativeBased = new AffirmativeBased(getAccessDecistionVoters());
return affirmativeBased;
}
// ... 생략 ...
}
안녕하세. 블로그 너무 잘봤습니다.. 평소에 스프링 시큐리티 공부하고싶었는데
이 블로그가 너무 큰 도움이 되었어요! 특히 class파일을 일일이 파헤쳐보며 로직을 검증하는게
너무 좋았어요 ㅎㅎ
시리즈 더 안나오나요?