Spring Security
스프링 시큐리티는 스프링 기반의 어플리케이션의 보안(인증과 권한)을 담당하는 프레임워크
보안관련 용어
- 접근 주체 (
Principal
) : 보호된 리소스에 접근하는 대상 - 인증 (
Authentication
) : 보호된 리소스에 접근한 대상에 대해 이 유저가 누구인지,Application
의 작업을 수행해도 되는지 확인하는 과정 - 인가 (
Authorize
) : 해당 리소스에 대해 접근 가능한 권한을 가지고 있는지 확인하는 과정 (After Authentication
) - 권한 : 인증된 주체가
Application
의 동작을 수행할 수 있도록 허락되어있는지를 결정- 권한 승인이 필요한 부분으로 접근하려면 인증 과정을 통해 주체가 증명 되어야만 한다
- 권한 부여에도 두가지 영역이 존재하는데 웹 요청 권한, 메소드 호출 및 도메인 인스턴스에 대한 접근 권한 부여
참고
https://spring.io/projects/spring-security
Spring Security
Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements
spring.io
기본 예제
1. 의존성 추가
// pom.xml <!-- thymeleaf --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- spring security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
2. HomeController 생성
// HomeController.java @Controller public class HomeController { @GetMapping(value="/hello") public String hello() { return "hello"; } @GetMapping(value="/my") public String my() { return "my"; } }
* Controller
가 다른 로직 없이 View Name
만 리턴해주는 용도 일 경우엔 View Controller
를 등록하여 사용할 수 있다.
// WebConfig.java @Configuration public class WebConfig implements WebMvcConfigurer { // 로직 없이 View 로만 보낼경우 사용 @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/helloView").setViewName("hello"); } }
3. 페이지 생성
// index.html <!DOCTYPE html> <html> <head> <meta charset='utf-8'> <title>Page Title</title> </head> <body> <h1>Welcome</h1> <a href="/hello">hello</a> <a href="/my">my page</a> </body> </html> // hello.html <!DOCTYPE html> <html> <head> <meta charset='utf-8'> <title>Page Title</title> </head> <body> <h1>Hello</h1> </body> </html> // my.html <!DOCTYPE html> <html> <head> <meta charset='utf-8'> <title>Page Title</title> </head> <body> <h1>My</h1> </body> </html>
4. HomeControllerTest 생성
// HomeControllerTest @RunWith(SpringRunner.class) @WebMvcTest(HomeController.class) public class HomeControllerTest { @Autowired MockMvc mockMvc; @Test public void hello() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.TEXT_HTML)) .andDo(MockMvcResultHandlers.print()) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.view().name("hello")) ; } @Test public void my() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/my")) .andDo(MockMvcResultHandlers.print()) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.view().name("my")) ; } }
결과 확인
스프링 시큐리티가 적용되어 있어 로그인 페이지가 나타나고, 로그인 이후 모든 페이지 접근이 가능하다.


스프링 부트 시큐리티 자동 설정
SecurityAutoConfiguration
: DefaultAuthenticationEventPublisher
가 등록되어있음(비밀번호 오류, 유저 미존재, 계정 만료 등등)
UserDetailsServiceAutoConfiguration
: Spring Boot App
구동 시 User 객체 하나를 inMemoryUserDetailsManager
를 만들어 제공
시큐리티 자동 설정 모방하기
WebSecurityConfig
생성 하여 기존 자동 설정을 사용하는 것과 동일한 결과를 나타낸다.
// WebSecurityConfig.java @Configuration public class WebSecurityConfig extends WebSecurityConfigurerAdapter { }
결국 동일한 결과를 나타내기 때문에 스프링 부트가 스프링 시큐리티 관련해서 해주는 것이 거의 없다고 보면 되고, inMemoryUserDetailsManager
를 이용해 User객체 하나 만드는 것 하나 정도만 수행한다.
하지만 그마저도 스프링 시큐리티를 적용하는 프로젝트들은 프로젝트만의 UserDetailsService
를 등록하게 되어있어 사실상 사용하는 것이 없다고 보면 된다.
테스트 오류 해결하기
1. 의존성 추가
// pom.xml <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <version>${spring-security.version}</version> <scope>test</scope> </dependency>
2. HomeControllerTest 수정
// HomeControllerTest.java @RunWith(SpringRunner.class) @WebMvcTest(HomeController.class) public class HomeControllerTest { @Autowired MockMvc mockMvc; @Test @WithMockUser // 가짜 User 인증정보 사용 public void hello() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.TEXT_HTML)) .andDo(MockMvcResultHandlers.print()) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.view().name("hello")) ; } @Test public void hello_without_user() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/hello")) .andDo(MockMvcResultHandlers.print()) .andExpect(MockMvcResultMatchers.status().isUnauthorized()) ; } @Test @WithMockUser public void my() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/my")) .andDo(MockMvcResultHandlers.print()) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.view().name("my")) ; } }
결과 확인

참고
https://docs.spring.io/spring-security/site/docs/current/reference/html5/#test-method
Spring Security Reference
In Spring Security 3.0, the codebase was sub-divided into separate jars which more clearly separate different functionality areas and third-party dependencies. If you use Maven to build your project, these are the modules you should add to your pom.xml. Ev
docs.spring.io
'Dev > Spring Boot' 카테고리의 다른 글
[스프링 부트 개념과 활용] 스프링 REST 클라이언트 1부 (0) | 2020.09.03 |
---|---|
[스프링 부트 개념과 활용] 스프링 시큐리티 2부 (0) | 2020.08.31 |
[스프링 부트 개념과 활용] 스프링 데이터 12부 (0) | 2020.08.31 |
[스프링 부트 개념과 활용] 스프링 데이터 11부 (0) | 2020.08.28 |
[스프링 부트 개념과 활용] 스프링 데이터 10부 (0) | 2020.08.28 |
댓글