Spring Security는 Spring Framework에서 인증과 권한 부여를 수행하는 데 사용되는 강력한 보안 프레임워크입니다. Spring Security는 Spring Framework에서 자체적으로 보안 구성을 제공하며, 다양한 보안 기능을 제공하는 다양한 확장 모듈을 제공합니다. 이번 글에서는 Spring Security를 사용하여 웹 보안을 구성할 때 사용하는 @EnableWebSecurity 어노테이션에 대해 알아보겠습니다.
1. @EnableWebSecurity 어노테이션
@EnableWebSecurity 어노테이션은 Spring Security를 사용하여 웹 보안을 구성할 때 사용하는 어노테이션입니다. 이 어노테이션을 사용하면 Spring Security와 관련된 구성을 할 수 있습니다. @EnableWebSecurity 어노테이션은 Spring Security의 기능을 활성화하고, WebSecurityConfigurerAdapter 클래스를 상속받은 설정 클래스를 등록합니다.
@EnableWebSecurity 어노테이션을 사용하면 다음과 같은 작업을 수행할 수 있습니다.
- HttpSecurity 객체를 사용하여 HTTP 요청에 대한 보안 구성을 설정할 수 있습니다.
- AuthenticationManagerBuilder 객체를 사용하여 사용자 인증 정보를 설정할 수 있습니다.
- WebSecurityConfigurerAdapter 클래스를 상속받은 설정 클래스를 등록할 수 있습니다.
@EnableWebSecurity 어노테이션은 Spring Security를 사용하여 웹 보안을 구성할 때 필수적으로 사용해야 하는 어노테이션입니다.
2. 예제
다음은 @EnableWebSecurity 어노테이션을 사용하여 Spring Security를 구성하는 간단한 예제 코드입니다.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.httpBasic();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("{noop}password").roles("USER");
}
}
위 예제 코드에서는 @EnableWebSecurity 어노테이션을 사용하여 Spring Security를 구성합니다. SecurityConfig 클래스는 WebSecurityConfigurerAdapter 클래스를 상속받아 구현되었습니다. configure(HttpSecurity http) 메서드를 사용하여 HTTP 요청에 대한 보안 구성을 설정하고, configure(AuthenticationManagerBuilder auth) 메서드를 사용하여 사용자 인증 정보를 설정합니다.
좀 더 다양한 케이스에 대해서 알아보겠습니다.
2-1.인증 필요 없는 URL 구성
인증이 필요하지 않은 URL 구성은 permitAll() 메서드를 사용하여 설정할 수 있습니다. 이 메서드는 인증 없이 접근 가능한 URL 패턴을 지정할 수 있습니다.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.httpBasic();
}
위 예제에서는 /public/** URL 패턴은 인증 없이 접근 가능하도록 설정됩니다.
2-2.권한 기반 접근 제어 구성
Spring Security를 사용하여 권한 기반 접근 제어를 구성하려면 hasRole() 또는 hasAuthority() 메서드를 사용하여 권한을 지정할 수 있습니다. 이 메서드는 인증된 사용자가 해당 권한을 가지고 있는 경우에만 접근이 허용됩니다.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasAuthority("USER")
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.httpBasic();
}
위 예제에서는 /admin/** URL 패턴은 ADMIN 권한이 있는 사용자만 접근할 수 있으며, /user/** URL 패턴은 USER 권한이 있는 사용자만 접근할 수 있도록 설정됩니다.
2-3.사용자 정의 로그인 페이지 구성
Spring Security를 사용하여 사용자 정의 로그인 페이지를 구성하려면 loginPage() 메서드를 사용하여 지정할 수 있습니다.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.and()
.httpBasic();
}
위 예제에서는 /login URL로 이동하면 사용자 정의 로그인 페이지가 표시됩니다.
2-4. 비밀번호 암호화 구성
Spring Security를 사용하여 비밀번호를 암호화하려면 PasswordEncoder 인터페이스를 사용하여 비밀번호를 암호화해야 합니다. Spring Security는 BCryptPasswordEncoder, NoOpPasswordEncoder 등 다양한 암호화 방법을 제공합니다.
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password(passwordEncoder().encode("password")).roles("USER");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
위 예제에서는 BCryptPasswordEncoder를 사용하여 passwordEncoder() 빈을 구성합니다. passwordEncoder() 빈을 구성한 후, configureGlobal() 메서드를 사용하여 인증 정보를 구성합니다. passwordEncoder() 빈을 사용하여 비밀번호를 암호화하면 인증 정보가 저장될 때 비밀번호가 암호화됩니다.
2-5. 로그아웃 구성
Spring Security를 사용하여 로그아웃을 구성하려면 logout() 메서드를 사용하여 지정할 수 있습니다. logout() 메서드는 로그아웃 URL 및 로그아웃 후 이동할 URL 등을 지정할 수 있습니다.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID");
}
위 예제에서는 /logout URL로 이동하면 로그아웃되며, 로그아웃 후 /login URL로 이동합니다. 또한 세션을 무효화하고 JSESSIONID 쿠키를 삭제합니다.
2-6. Remember-me 구성
Spring Security를 사용하여 Remember-me 기능을 구성하려면 rememberMe() 메서드를 사용하여 지정할 수 있습니다.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.rememberMe()
.key("myKey")
.tokenValiditySeconds(86400);
}
위 예제에서는 rememberMe() 메서드를 사용하여 Remember-me 기능을 활성화합니다. key() 메서드는 Remember-me 토큰을 생성하는 데 사용될 키를 지정하고, tokenValiditySeconds() 메서드는 Remember-me 토큰의 유효 시간을 지정합니다.
2-7. CORS 구성
Spring Security를 사용하여 CORS(Cross-Origin Resource Sharing)를 구성하려면 cors() 메서드를 사용하여 지정할 수 있습니다.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.configurationSource(corsConfigurationSource())
.and()
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
configuration.setAllowedHeaders(Arrays.asList("*"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
위 예제에서는 cors() 메서드를 사용하여 CORS 구성을 지정합니다. configurationSource() 메서드는 CorsConfigurationSource 인스턴스를 반환하는 메서드입니다. 이 인스턴스는 allowedOrigins, allowedMethods, allowedHeaders와 같은 CORS 구성을 지정합니다. UrlBasedCorsConfigurationSource는 URL 패턴별로 CorsConfiguration 객체를 관리하는데 사용됩니다.
2-8. 예외 처리 구성
Spring Security를 사용하여 예외 처리를 구성하려면 exceptionHandling() 메서드를 사용하여 지정할 수 있습니다.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling()
.accessDeniedPage("/access-denied")
.and()
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin();
}
위 예제에서는 exceptionHandling() 메서드를 사용하여 예외 처리를 구성합니다. accessDeniedPage() 메서드는 접근이 거부되었을 때 이동할 페이지를 지정합니다. authenticationEntryPoint() 메서드는 인증되지 않은 사용자가 보호된 리소스에 액세스하려고 할 때 호출됩니다.
2-9. Http Security를 통한 접근 권한 설정
Spring Security를 사용하여 Http 요청에 대한 접근 권한을 설정하려면 HttpSecurity 객체를 사용하여 지정할 수 있습니다. HttpSecurity 객체는 authorizeRequests() 메서드를 사용하여 지정할 수 있습니다.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("ADMIN", "USER")
.anyRequest().authenticated()
.and()
.formLogin();
}
위 예제에서는 authorizeRequests() 메서드를 사용하여 Http 요청에 대한 접근 권한을 설정합니다. antMatchers() 메서드를 사용하여 URL 패턴을 지정하고, hasRole() 메서드를 사용하여 역할을 지정합니다. hasAnyRole() 메서드를 사용하면 여러 역할을 지정할 수 있습니다. anyRequest() 메서드는 나머지 요청에 대한 접근 권한을 설정합니다.
2-10. 정적 자원 보안 구성
Spring Security를 사용하여 정적 자원에 대한 보안을 구성하려면 WebSecurity 객체를 사용하여 지정할 수 있습니다. WebSecurity 객체는 ignoring() 메서드를 사용하여 지정할 수 있습니다.
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/**");
}
위 예제에서는 configure(WebSecurity web) 메서드를 사용하여 정적 자원에 대한 보안을 구성합니다. ignoring() 메서드를 사용하여 무시할 URL 패턴을 지정합니다.
이상으로 Spring Security의 기본적인 사용 방법과 다양한 구성 예제에 대해 알아보았습니다. Spring Security는 보안 관련 다양한 기능을 제공하며, 많은 설정이 가능합니다. 이를 통해 안전한 웹 애플리케이션을 개발할 수 있습니다.
추가로, Spring Security는 OAuth, OpenID Connect 등의 인증 프로토콜을 지원하여 편리한 인증 구현이 가능합니다. 또한, JWT와 같은 토큰 기반 인증도 지원합니다.
Spring Security의 기능을 모두 다루기에는 너무 방대하므로, 이 글에서는 Spring Security의 기본적인 사용 방법과 예제에 대해 알아보았습니다
정리
이번 글에서는 Spring Security를 사용하여 웹 보안을 구성할 때 사용하는 @EnableWebSecurity 어노테이션에 대해 알아보았습니다. @EnableWebSecurity 어노테이션은 Spring Security와 관련된 구성을 활성화하고,
'spring > study' 카테고리의 다른 글
[Spring] Swagger에 대해서 알아보자 (0) | 2023.02.23 |
---|---|
[Spring] MockitoExtension에 대해서 알아보자 (0) | 2023.02.18 |
[Spring] @OnDelete 에 대해서 알아보자 (0) | 2023.02.16 |
[Spring] @Query 에 대해서 알아보자 (0) | 2023.02.15 |
[Spring] @Autowired 에 대해서 알아보자 (0) | 2023.02.14 |