Spring Security - Authentication

최상민·2023년 11월 27일
0

Spring Boot

목록 보기
2/5

Spring Security

Spring Security는 Java 애플리케이션에 인증과 권한 부여를 모두 제공하는 데 중점을 둔 프레임워크이다. 기본적으로 인증 절차 후 인가 절차를 진행하며, Principal(접근 주체)와 Credential(자격 증명)을 사용하여 절차가 진행된다.

  • 인증(Authenticaiton): 해당 사용자가 본인이 맞는지 확인하는 절차
  • 인가(Authorization): 인증된 사용자가 요청한 자원에 접근 가능한가를 결정하는 절차

Security와 관련된 Configuration은 WebSecurityConfigurerAdapter에서 설정할 수 있다.

AuthenticationManager

스프링의 인증은 AuthenticationManager라는 API가 관리한다. 중간과정이 있긴 한데 축소시켜서 이야기하자면 인증 과정에 대해 AuthenticationProviderAuthenticationManager에 주입해 특정 종류의 인증을 진행하게 할 수 있다. 예컨대 DaoAuthenticationProvider의 경우 사용자의 이름과 비밀번호를 기반한 인증을, JwtAuthenticationProvider는 JWT 토큰에 기반한 인증을 진행한다.

AuthenticationManagerWebSecurityConfigurerAdapter에서 configure 함수에서 AuthenticationManagerBuilder를 통해 설정할 수 있다.

  • Code (SecurityConfiguration extends WebSecurityConfigurerAdapter - configure)
    //인증 관리자
        @Override
        protected void configure(AuthenticationManagerBuilder auth) {
            auth.authenticationProvider(authenticationProvider(userService));
        }

DaoAuthenticationProvider

DaoAuthenticationProviderUserDetailsServicePasswordEncoder를 이용해 인증을 진행한다. DaoAuthenticationProvider를 사용하기 위해서는 위의 두 필드를 설정해줘야한다. UserDetailsService의 경우 UserDetails loadUserByUserName(String username)만이 정의된 interface이다. 이를 implement한 서비스를 필드로 넘겨준다. 이 때 반드시 정의되어야 하는 loadUserByUserName 함수의 경우 UserDetails 타입 객체를 반환한다.

UserDetails 객체 interface에는 몇 가지 필드에 대한 Getter 함수가 정의되어있다. 즉, 해당 필드와 Getter 함수가 반드시 필요하다. 따라서 UserDetails를 implement하는 객체(우리가 사용할 User 객체)는 다음과 같은 형태로 작성할 수 있다.

  • Code
    • UserDetails

      @Data
      public interface UserDetails {
          private Collection<? extends GrantedAuthority> authorities;
          private String password;
          private String username;
          private boolean accountNonExpired;
          private boolean accountNonLocked;
          private boolean credentialsNonExpired;
          private boolean enabled;
      }
    • User implements UserDetails

      @Data
      public class User implements UserDetails {
          private List<UserGrantedAuthority> authorities;
          // authorities는 List가 아니라 Map, Set 등 다른 Collection이 될 수도 있다.
      		// UserGrantedAuthority는 GrantedAuthority를 implement하는 사용자 정의 객체이다.
          private String password;
          private String username;
          private boolean accountNonExpired;
          private boolean accountNonLocked;
          private boolean credentialsNonExpired;
          private boolean enabled;
          // 그 외의 사용자 정의 함수
      }

다른 건 다 그렇다 치지면 여기 또 다른 객체 GrantedAuthority가 있다. 의외로 간단히 authority의 Getter 함수만 정의된 interface이다. 따라서 해당 객체는 다음과 같은 형태로 작성할 수 있다.

  • Code (UserGrantedAuthority implements GrantedAuthority)
    @Data
    public class UserGrantedAuthority implements GrantedAuthority {
        String authority; // 권한
    }

여기서 받게되는 authority가 나중에 접근 보안 설정 관리자에서 hasAuthority에 해당하게 된다.

http.authorizeRequests().antMatchers("/home").hasAuthority("ADMIN") 
// ADMIN 권한의 유저만 "/home" 에 접근가능
💡 Authority는 Role은 비슷하지만 조금 다르다. Role은 Admin, Manager와 같이 역할을 말하는 것이고, Authority는 그 역할이 가지는 권한, 예컨대 READ_ARTICLE, WRITE_ARTICLE 등을 말한다. Spring Security에서는 authority는 보통 Role로 혼용되어 사용된다.

Authority에 따른 접근보안 설정

  • SecurityConfiguration extends WebSecurityConfigurerAdapter
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
        .antMatchers("/home").hasAuthority("READ");
				// List<UserGrantedAuthority> authorities에 "READ"가 포함된 사용자만 접근

    http
        .authorizeRequests()
        .antMatchers("/home").hasRole("ADMIN");
				// hasRole함수는 자동으로 앞에 "ROLE_"을 접두사로 붙여준다.
				// List<UserGrantedAuthority> authorities에 "ROLE_ADMIN"이 포함된 사용자만 접근

}

관련 코드는 아래 깃헙을 참고해주세요.
Spring Security Github

profile
상민

0개의 댓글