📌 Intro
- 항해99 주특기 숙련주차에서 처음 Spring Security를 접하고 미니프로젝트 주차에서도 Spring Security를 접했다. 물론 숙련주차에서 작성한 코드를 기반으로 했지만 Spring Security는 너무 어렵다...그리고 너무 내용이 방대하다..
- 이번 포스팅에서는 간단하게 Spring Security 사용법과 메소드들을 쭉 나열하고 어떤 기능인지 적어봤다. 일단 이론적인 부분들로만 채웠는데 포스팅을 하면서 느낀 것은(포스팅 다하고 Intro 적는중..) Spring Security 프로젝트를 하나 만들어서 내가 직접 이것 저것 해봐야겠다..!는 것이다.
- Spring Security 프로젝트를 하나 파서 나중에 에러나는 부분들이나 에러를 해결하는 부분들을 잘 정리해보려고 한다!
Spring Security란?
Spring Security(스프링 시큐리티) : 스프링 서버에 필요한 인증 및 인가를 위해 많은 기능을 제공하는 프레임워크
📍 간단한 사용방법
1. Spring initializr에서 추가 or build.gradle에 추가
implementation 'org.springframework.boot:spring-boot-starter-security'
2. Security Config 설정
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.defaultSuccessUrl("/")
.permitAll()
.and()
.logout()
.permitAll();
}
}
- Spring security 5.7버전 이상부터 WebSecurityConfigurerAdapter가 deprecated 되었습니다. 스프링 부트 버전을 Spring security가 5.7 아래 버전을 사용하는 버전(2.6.x)으로 변경해주세요!
3. h2-console을 사용할 경우
- h2-console 사용에 대한 허용 (CSRF, FrameOptions 무시)
@Override
public void configure(WebSecurity web) {
web
.ignoring()
.antMatchers("/h2-console/**");
}
- Springboot 2.7.1버전 사용하기 때문에 WebSecurityConfigurerAdapter가 deprecated된 경우 해결법!
4. 비밀번호 암호화를 위해 Bean 등록
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Bean
public BCryptPasswordEncoder encodePwd() {
return new BCryptPasswordEncoder();
}
📍 WebSecurityConfig 메소드 및 어노테이션 정리
1. 인증관련 메소드
- 앞에 http.authorizeRequests()가 붙는다.
- ex) access() -> http.authorizeRequests().access()라는 의미
- authorizeRequests() : 시큐리티 처리에 HttpServletRequest를 이용한다는 것을 의미
- HttpServletRequest란?
- access(hasRole(USER)) : 주어진 SpEL 표현식의 평가 결과가 true이면 접근을 허용
- anonymous() : 익명의 사용자의 접근을 허용
- antMatchers(antPatterns 경로) :
- ant : 아래 번외1)에서 설명.
- Matchers : URL 또는 대상 문자열에서 패턴이 일치하는 부분을 찾거나 전체 일치 여부 등을 판단
- authenticated() : 인증된 사용자의 접근을 허용
- denyAll() : 무조건 접근을 허용하지 않음
- fullyAuthenticated() : 사용자가 완전히 인증되면 접근을 허용(기억되지 않음)
- hasAnyAuthority(String...) : 사용자가 주어진 권한 중 어떤 것이라도 있다면 접근을 허용
- hasAnyRole(String...) : 사용자가 주어진 역할 중 어떤 것이라도 있다면 접근을 허용
- hasAuthority(String) : 사용자가 주어진 권한이 있다면 접근을 허용
- hasIpAddress(String) : 주어진 IP로부터 요청이 왔다면 접근을 허용
- hasRole(USER) : 사용자가 주어진 역할이 있다면 접근을 허용
- not() : 다른 접근 방식의 효과를 무효화
- permitAll() : 무조건 접근을 허용
- rememberMe() : 기억하기를 통해 인증된 사용자의 접근을 허용
2. 인가관련 메소드
- http.formLogin() : 로그인 기능
- .loginPage(URL) : 로그인 페이지 URL 설정
- .loginProcessingUrl(URL) : 로그인 처리(로그인 버튼 눌렀을 때) URL 설정 => POST URL
- .successHandler(new CustomAuthenticationSuccessHandler())
- .failureHandler(new CustomAuthenticationFailureHandler())
- .defaultSuccessUrl(URL) : 로그인 처리 후 성공 시 URL
- .permitAll() : 로그인 처리 후 실패 시 URL, 로그인 처리 후 실패 시 이전 경로로 간다.(이해 잘 안감.)
- http.logout() : 로그아웃 기능
- .logoutUrl(URL) : 로그아웃 요청 URL
- http.csrf().disable() : csrf() 설정을 안해도 된다는 의미
- csrf() : csrf를 막기 위한 설정
- csrf란 무엇인가? 👉🏻 번외2)에서 설명
- 왜 csrf()를 disable()하는 것일까?는 아래의 블로그에 너무 정리가 잘 되어있다.
- http.httpBasic() :
- http.sessionManagement() : 세션 관리 기능 설정
- .invalidSessionUrl(URL) : 세션이 유효하지 않을 때 이동 할 페이지
- .maximumSessions(int타입) : 최대 허용 가능 세션 수, -1은 무제한
- .maxSessionsPreventsLongin(불린 타입) : 동시 로그인 차단, default는 false(기존 세션 만료)
- .sessionFixation().changeSessionId() : 기본값 -> 세션은 유지하되 세션 아이디는 계속 새로 발급(servlet 3.1이상 기본 값) 살짝 이해 안감..
- none() : 세션이 새로 생성되지 않고 그대로 유지되기 때문에 세션 고정 공격에 취약하다.
- migrateSession() : 새로운 세션도 생성되고 세션 아이디도 발급된다. (sevlet3.1 이하 기본 값) + 이전 세션의 속성값들도 유지된다.
- newSession() : 세션이 새롭게 생성되고, 세션 아이디도 발급되지만, 이전 세션의 속성값들을 유지할 수 없다.
- .expireUrl(URL) : 세션이 만료된 경우 이동할 페이지
- http.rememberMe() : rememberMe 기능 작동 설정
- remember me?
- SessionID 쿠키를 삭제하더라도 Remember-Me가 있다면 해당 쿠키를 decoding한 다음 로그인 상태를 유지할 수 있도록 한다.
- .rememberMeParameter(파라미터명) : 파라미터 설정, default는 "remember-me"
- .tokenValiditySeconds(초) : 토큰 유효기간 설정, default는 14일
- .alwaysRemember(불린타입) : remember me 기능이 활성화되지 않아도 항상 실행, default는 false
- .userDetailsService(userDetailsService) : remember me에서 시스템에 있는 사용자 계정을 조회할 때 사용
- .deleteCookies(파라미터명) : 쿠키 삭제 기능, 설정해준 파라미터명을 넣어준다.
- http.ExceptionHandling() : 예외처리 기능이 작동
- .authenticationEntryPoint(new AuthenicationEntryPoint()) : 인증예외 발생시 수행 메서드(commence) 오버라이딩. 해당 코드에서는 login페이지로 이동시키지만 다른 로직을 수행할 수도 있다.
- .accessDeniedHandler(new AccessDeniedHandler() : 인가예외 발생시 처리 로직 수행 해당 코드에서는 denied페이지로 이동하지만 별도로 다른 로직을 수행할 수 있다.
- .onAuthenticationSuccess : savedRequest객체에 RequestCache객체가 담고 있는 사용자가 원래 가려던(요청하려던) 자원의 요청정보를 가져와 활용할 수 있도록 한다.
3. 어노테이션
- @EnableWebSecurity : 웹보안 활성화를위한 어노테이션 스프링 시큐리티 지원을 가능하게 한다.
- @EnableWebSecurity 어노테이션을 WebSecurityconfigurerAdapter를 상속하는 설정 객체를 붙혀주면 SpringSecurityFilterChain에 등록된다.
번외1) antMatchers에서 ant란?
"ant" 의 어원은 Apache Ant Project 에서 가져온거다.
Apache Ant Project 는 xml 스크립트 언어를 사용하는 자바 빌드 시스템이다.
Apache Ant Home 또는 Spring 공식문서에서 말하기를
매핑되는 부분 (resource-path)은 Apache Ant 의 기술을 빌려쓴? 것이다.
간단히 정리해서 말하자면 "antMatcher" 는 url패턴과 자원을 매핑할 때 사용하는 하나의 Style(기법)이라고 생각하면 된다.
-
Ant-style path patterns
-
블로그 참고
번외2) CSRF관련
-
CSRF란?
CSRF (Cross Site Request Forgery) : 다른 사이트에서 유저가 보내는 요청을 조작하는 공격. 예시로는 이메일에 첨부된 링크를 누르면 내 은행계좌의 돈이 빠져나가는 방식의 해킹 등이 있다.
-
CSRF 토큰이란?
CSRF TOKEN : 회원가입시 페이지를 바꿔치기 하는등의 방법으로 해킹을 하기도 하기 때문에 서버에 들어온 요청이 실제 서버에서 허용한 요청이 맞는지 확인하기 위한 것이 CSRF 토큰이다.
-
CSRF 토큰 로직
참고자료
- CSRF토큰이란?
- [스프링프레임워크] 스프링 시큐리티 -3. 요청 가로채기
- Spring Security :: CSRF protection disable option 대한 생각 정리
- Spring security - csrf란?
- Ant-style path patterns
- "Ant"Matchers