Spring Security는 스프링 기반의 어플리케이션 보안을 담당하는 프레임워크입니다. Spring Security를 사용하면 사용자 인증, 권한, 보안처리를 간단하지만 강력하게 구현 할 수 있습니다.
해당 글에서는 WebSecurityConfigurerAdapter 방식을 사용하였습니다. SecurityFilterChain는 리팩토링해야합니다.
java Web project에 보안을 설정하기 위해선 설정 파일을 상속받고 원하는 Method를 Override하여 작성 하면 됩니다. 기본적인 구성은 다음과 같습니다.
@Configuration
@EnableWebSecurity // WebSecurityConfigurerAdapter에 필요한 Bean들이 import됩니다.
@Slf4j
@Order(1) // SecurityConfig가 여러개라면 순서를 지정해줄 수 있습니다.
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().requestMatchers(PathRequest.toStaticResources().atCommonLocations());
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/guest/**").permitAll()
.antMatchers("/manager/**").hasRole("MANAGER")
.antMatchers("/admin/**").hasRole("ADMIN");
http.formLogin();
http.exceptionHandling().accessDeniedPage("/accessDenied");
http.logout().logoutUrl("/logout").invalidateHttpSession(true);
}
위에서는 두가지 다른 매개변수를 갖는 configure
메서드를 불러옵니다.
web을 인자로 갖는 메서드입니다. 다음과 같이 선언하면 영어그대로 해석되듯 정적자원 (css, image, js)들은 인증과 인가 처리를 하는 작업에서 제외를 해줍니다.
web.ignoring().requestMatchers(PathRequest.toStaticResources().atCommonLocations());
http를 인자로 갖습니다. 기본적으로 사용할 수 있는 인증 인가 프로세스를 정의 가능합니다.
http.authorizeRequests()
.antMatchers("/guest/**").permitAll()
.antMatchers("/manager/**").hasRole("MANAGER")
.antMatchers("/admin/**").hasRole("ADMIN");
http.formLogin().loginPage("/login");
//.passwordParameter()
//.usernameParameter()
http.logout().logoutUrl("/logout").invalidateHttpSession(true);
http
: HttpSecurity 타입에 변수를 선언하므로써 설정을 시작합니다. 각 기능들은 chain형식으로 이루어져있고 편의상 3개로 나누었지만, login, logout전부 하나에 chain형식으로도 작성 가능합니다..authorizeRequests()
: 앞으로 작성할 요청에 대한 권한을 설정할 수 있습니다..antMatchers("/guest/**").permitAll()
: guset로 된 모든 하위주소들은 권한을 가진사용자뿐만 아니라 비회원 즉 모두가 출입가능합니다..hasRole("MANAGER")
: 해당 매서드를 설정하면 회원 권한등급 중 Manager만 가능한 주소가 됩니다.http.formLogin()
: <form>
기반의 요청을 이용하여 로그인을 하겠다는 겁니다..loginPage("/login")
: 로그인 페이지를 따로 /login
로 설정합니다 . Spring Security는 기본적으로 내장되어있는 login페이지를 제공합니다만, 직접 만들어 사용할때는 이 매서드를 사용하여 해당페이지를 매핑해주시면 됩니다. 이때 위에서 선언하였듯, <form>
기반으로 만드셔야합니다..passwordParameter()
, .usernameParameter()
: 기본적으로 Security는 parameter name을 username
과 password
로 명명합니다만, 원하는 parameter가 있다면 직접 설정해주실수도 있습니다. uesrId
라던가, pwd
라던가...http.logout()
: 로그아웃 프로세스를 진행하게 합니다..logoutUrl("/logout")
: 로그인과 똑같습니다. 내부적으로 페이지를 제공은 하지만 커스텀하고 싶다면 사용하시면 됩니다. 내부적으로 세션을 지우거나 쿠키를 지우는 작업을 만들어 놓으셔야합니다..invalidateHttpSession(true)
: security에서 제공하는 .logout()
만을 사용해도 세션처리는 해줍니다만, 세션은 만기시키는 매서드가 있다정도만 아시면 됩니다. http.authorizeRequests()
.antMatchers("/guest/**").permitAll()
.antMatchers("/manager/**").hasRole("MANAGER")
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated(); // 어떠한 요청도 인증된 사용자만 허용, permitAll() 반대기능
인가확인을 위한 작업은 순서대로 진행됩니다.
1. url이 guest인지 보고 > 모두허용
2. url이 manager인지 보고 > manager만 허용
3. admin....
4. 그 외 모든 요청, 회원이면 전부 이용가능.
그럼 다음 내용을 보시죠.
http.authorizeRequests()
.anyRequest().authenticated()
.antMatchers("/guest/**").permitAll()
.antMatchers("/manager/**").hasRole("MANAGER")
.antMatchers("/admin/**").hasRole("ADMIN")
;
이런식으로 구성되어있으면 어떠한 요청도 인증을 받아야 진입이 가능해지니, /guest/**
는 더이상 필요없어집니다.
표현식 | 방식 |
---|---|
authenticated() | 인증된 사용자의 접근을 허용 |
fullyAuthenticated() | 인증된 사용자의 접근을 허용, rememberMe 인증 제외 |
permitAll() | 무조건 접근을 허용 |
denyAll() | 무조건 접근을 허용하지 않음 |
anonymous() | 익명사용자의 접근을 허용 |
rememberMe() | 기억하기를 통해 인증된 사용자의 접근을 허용 |
access(String) | 주어진 SpEL 표현식의 평가 결과가 true이면 접근을 허용 |
hasRole(String) | 사용자가 주어진 역할이 있다면 접근을 허용 |
hasAuthority(String) | 사용자가 주어진 권한이 있다면 |
hasAnyRole(String...) | 사용자가 주어진 권한이 있다면 접근을 허용 |
hasAnyAuthority(String...) | 사용자가 주어진 권한 중 어떤 것이라도 있다면 접근을 허용 |
hasIpAddress(String) | 주어진 IP로부터 요청이 왔다면 접근을 허용 |
이 처럼 Config로 간단하게 인증 인가가 되는 Web 프로젝트를 구성가능합니다.
다음 포스트에서는 보안정책, 예외 핸들러와 Provider를 통한 CustomUser인증을 진행하겠습니다.