Spring Boot

[SPRING] 스프링시큐리티(Spring Security)를 사용해보장

재원쓰 2022. 12. 23. 11:23

Maven Dependency

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Gradle Dependency

implementation 'org.springframework.boot:spring-boot-starter-security'

 

어노테이션

@Configuration

설정 컴포넌트라고 선언한다.

@EnableWebSecurity

스프링 시큐리티 지원을 가능하게 한다. 이걸 설정 객체에 붙혀주면 SpringSecurityFilterChain에 등록된다.

@AuthenticationPrincipal

매개변수에 선언한다. 이게 붙은 매개변수는 SecurityContextHolder에 저장된 인증 객체(Authentication 객체)의 principal 부분(userDetails)을 가져온다.

@Secured("ROLE_ADMIN")

내가 허가할 권한을 넣어준다. 

@EnableGlobalMethodSecurity(securedEnabled = true)

Secured 어노테이션을 사용할 수 있게 해주려면 WebSecurityConfig쪽에 이 어노테이션을 선언해줘야 한다.

 

객체

WebSecurityConfigurerAdapter

  • Security Dependency를 추가한 이후 기본적인 security를 설정및 구현하는 클래스
  • HttpSecurity 라는 세부적인 보안기능을 설정할수 있는 API를 제공하는 클래스를 생성한다.

SecurityFilterChain

  • Filter 보다 먼저 실행된다. 여러개의 SecurityFilterChain을 @Order를 통해 여러개를 만들어 순서를 정할 수 있다.

HttpSecurity

  • csrf().disable() : 사이트간 요청 위조. csrf가 설정되어있으면 html에서 CSRF 토큰값을 넘겨주어야 요청 수신이 가능하다. 쿠키를 사용하기 때문에 html 관련이라서 REST API에서는 disable이 가능하다.

SecurityContextHolder

스프링 시큐리티로 인증을 한 사용자의 상세 정보를 저장한다.

SecurityContext 란? SecurityContextHolder 로 접근할 수 있으며 Authentication 객체를 가지고 있다.

PasswordEncoder

암호화된 비밀번호이다. 암호화 종류가 많은데 BCryptPasswordEncoder를 사용하자.

 

제공 API

인증 API 인가 API
http.formLogin() http.authorizeRequests().antMatchers(/admin)
http.logout() http.authorizeRequests().hasRole(USER)
http.csrf() http.authorizeRequests().permitAll()
http.httpBasic() http.authorizeRequests().authenticated()
http.SessionManagement()
 
http.authorizeRequests().fullyAuthentication()
http.RememberMe() http.authorizeRequests().access(hasRole(USER))
http.ExceptionHandling() http.authorizeRequests().denyAll()
http.addFilter()  

antMatchers 속성 

permitAll : 전부 허가한다

authenticated : 인증을 한다.

anonymous : 익명의 사용자만 허용한다.

hasAnyRole : 권한을 가진 사용자만 요청을 받아들인다.

등등...

Security Config 설정

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity // 스프링 Security 지원을 가능하게 함
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests() // 요청에 의한 보안검사 시작
                .antMatchers("/images/**").permitAll() // image 폴더를 login 없이 허용
                .antMatchers("/css/**").permitAll() // css 폴더를 login 없이 허용
                .anyRequest().authenticated() // 어떤 요청이든 보안검사를 한다.
                .and()
		            // 로그인 세팅 코드
                    .formLogin() // 보안 검증은 formLogin방식으로 하겠다.
                    .loginPage("/user/login") //사용자 정의 로그인 페이지
                    .defaultSuccessUrl("/") //로그인 성공 후 이동 페이지
                    .failureUrl("/user/login?error") // 로그인 실패 후 이동 페이지
                    .usernameParameter("username")//아이디 파라미터명 설정
                    .passwordParameter("password")//패스워드 파라미터명 설정
                    .loginProcessingUrl("/login")//로그인 Url을 변경 가능
                    .successHandler(loginSuccessHandler())//로그인 성공 후 핸들러 (해당 핸들러를 생성하여 핸들링 해준다.)
                    .failureHandler(loginFailureHandler());//로그인 실패 후 핸들러 (해당 핸들러를 생성하여 핸들링 해준다.)
                    .permitAll() //사용자 정의 로그인 페이지 접근 권한 승인
                .and()
					// 로그아웃 세팅 코드
                    .logout() //로그아웃 처리
                    .logoutUrl("/logout")// 로그아웃 처리 URL
                    .logoutSuccessUrl("/login")//로그아웃 성공 후 이동페이지
                    .deleteCookies("JSESSIONID","remember-me")//로그아웃 후 쿠키 삭제
                    .addLogoutHandler(new LogoutHandler() {
                    	@Override
                    	public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
                            HttpSession session = request.getSession();
                            session.invalidate();
                        }
                    })//로그아웃 핸들러
                    .logoutSuccessHandler(new LogoutSuccessHandler() {
                    	@Override
                        public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                            response.sendRedirect("/login");
                        }
                    })//로그아웃 성공 후 핸들러
                    .deleteCookies("remember-me");//쿠키 삭제
                    .permitAll();
    }
}

 

 

모르는 용어

WebSecurityCustomizer
requestMatchers
PathRequest
atCommonLocations
HttpSecurity
exceptionHandling : 에러가 날때 핸들링
- accessDeninedPage : 403 에러 처리. 인증과는 별개로 추가적인 권한이 충족하지 않은 경우
- authenticationEntryPoint : 401 에러 처리. Authorization 즉, 인증과정에서 실패할 경우
addFilterBefore