Backend/Spring

[Spring] Spring Security 로그인 계정 추가 및 자동 로그인 기능 설정하기

mirae.kwak 2022. 9. 1. 17:08
728x90

Spring Security 로그인

Spring Security 시작하기 포스팅에서 자동으로 생성되는 password를 사용하여 로그인 하는 방식 대신 임의적으로 application.yml 파일에 user와 password, 권한 설정을 해주어 로그인할 수 있었다. 

spring:
  application:
    name: spring security 01
  thymeleaf:
    cache: true
  security:
    user:
      name: user
      password: user123
      roles: USER
  messages:
    basename: i18n/messages
    encoding: UTF-8
    cache-duration: PT1H
server:
  port: 8080

설정파일에서 security에 user를 추가하는 방식으로 가능하지 않을까 생각할  수 있지만 이 방식으로는 여러명의 로그인 계정을 추가할  수 없다.

  • 설정 파일을 바인딩하는 SecurityProperties에는 하나의 User를 가지고 있음.
    • 즉 설정파일에서 여러개의 user를 둘 수가 없음

 

Spring Security 로그인 계정 추가

cofigure(AuthenticationManagerBuilder auth) 메소드 override

  • WebSecurityConfigureAdapter를 상속받은 후 configure 메소드를 오버라이드함
  • passwordEncoder는 NoOpPasswordEncoder로 사용함
  • 기본 로그인 계정을 AuthenticationManagerBuilder 클래스를 통해 추가함
@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user").password("user123").roles("USER")
                .and()
                .withUser("admin").password("admin123").roles("ADMIN")
                ;
    }

 

password 설정 시 주의점!

  • inMemoryUserDetailsManager에서 user정보를 가져와서 password check함
  • 이때 PasswordEncoder를 사용하는데 defaultPasswordEncoder로서 UnmappedIdPasswordEncoder 객체를 사용 사용함. 
    • UnmappedIdPasswordEncoder는 올바르지 않은 상황에 대해 예외를 발생시키기위한 구현으로 실질적인 기능이 구현되어 있지 않음
  • Spring Security 5에서는 DelegatingPasswordEncoder(구현체) 클래스가 기본 PasswordEncoder(인터페이스)로 사용됨
  • DelegatingPasswordEncoder 클래스는 패스워드 해시 알고리즘 별로 PasswordEncoder를 제공하는데, 해시 알고리즘별 passwordEncoder 선택을 위해 패스워드 앞에 prefix를 추가함
{bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
{noop}password // encoding 안했을 경우 noop
{pbkdf2}5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc
{sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0
  • prefix 부분이 생략되는 경우 기본 PasswordEncoder로 bcrypt가 사용됨
  • password 해시 알고리즘을 변경하거나, 강력한 해시 알고리즘을 사용하여 password를 업그레이드 할 수 있도록 함
    • InMemoryUserDetailsManager 객체(보다 정확하게는 UserDetailsPasswordService 인터페이스 구현체)를 사용한다면 최초 로그인 1회 성공시, {noop} 타입에서 -> {bcrypt} 타입으로 PassEncoder가 변경된다.
    • password가 업그레이드 됐다!
  • DelegatingPasswordEncoder 사용이 필요 없다면 BCryptPasswordEncoder 클래스를 명시적으로 Bean 선언하면됨

 

Spring Security 로그아웃, Cookie 기반 자동 로그인(Remember-me) 기능

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
      .authorizeRequests()
        .antMatchers("/me").hasAnyRole("USER", "ADMIN")
        .anyRequest().permitAll()
        .and()
      .formLogin()
        .defaultSuccessUrl("/")
        .permitAll()
        .and()
      /**
       * remember me 설정
       */
      .rememberMe()
        .rememberMeParameter("remember-me")
        .tokenValiditySeconds(300)
        .and()
      /**
       * 로그아웃 설정
       */
      .logout()
        .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
        .logoutSuccessUrl("/")
        .invalidateHttpSession(true)
        .clearAuthentication(true)
    ;
}
  • logout
    • 로그아웃 클릭 시 /logout으로 이동하도록 했기 때문에 logout과 매치되도록 함
      • logoutRequestMatcher : /logout이 default 값
    • invalidateHttpSession : 로그아웃이 성공 했을 때 해당 사용자의 세션을 invalidate 시킴
      • default : true
    • clearAuthentication : 로그아웃된 사용자의 security context authentication 값을 null로 바꿈
      • default : true
  • Remember-me
    • spring security 로그인 창에서 체크박스로 remember me 선택 가능

 

728x90