본문 바로가기

Spring/Spring Security

UserDetailService & PasswordEncoderFactories

반응형

UserDetailService

유저 정보를 가지고, 인증을 하는 인터페이스이다.

이 인터페이스를 이용하여, DAO (DataAccessObject)를 통해서 DB에 저장되어 있는 유저 정보를 이용하여 인증을 하도록 구현체를 생성하여 커스터마이징 할 수 있다.

Spring Security는 인증 사용자 정보를 UserDetails 타입의 객체를 통해 관리한다.

https://www.javarticles.com/2017/04/spring-security-jdbcuserdetailsmanager-example.html

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Account account = accountRepository.findByUsername(username);
        if (account == null) {
            throw new UsernameNotFoundException(username);
        }

        return new UserAccount(account);
    }

User 정보를 저장하고 있는 AccountRepository 에서 유저 정보가 존재하지 않을 경우, UsernameNotFoundException 을 발생시키고, 있을 경우에는, UserDetails 타입으로 변환하여 리턴한다.

Spring Security는 UserDetails의 기본 구현체인 User를 제공한다.

org.springframework.security.core.userdetails.User

public class User implements UserDetails, CredentialsContainer {
    private static final long serialVersionUID = 510L;
    private static final Log logger = LogFactory.getLog(User.class);
    private String password;
    private final String username;
    private final Set authorities;
    private final boolean accountNonExpired;
    private final boolean accountNonLocked;
    private final boolean credentialsNonExpired;
    private final boolean enabled;
    
    // ...
    
    

org.springframework.security.core.userdetails.UserDetails

public interface UserDetails extends Serializable {
    Collection<? extends GrantedAuthority> getAuthorities();

    String getPassword();

    String getUsername();

    boolean isAccountNonExpired();

    boolean isAccountNonLocked();

    boolean isCredentialsNonExpired();

    boolean isEnabled();
}

하지만 Spring Security에서 제공하는 User 클래스에는 기본 정보만 가지고 있기 때문에

추가적인 정보를 저장하고자 할 경우에는, 이를 상속받아 UserDetails 구현체를 만들어줘야하는 할 것이다.

Spring Security 5.0 부터 제공하는 PasswordEncoderFactories

Password Encoder 구현체를 Bean에 등록하여 사용하기 위해 직접 DelegatingPasswordEncoder를 생성하여 Bean에 등록해야 했다.

그러나, PasswordEncoderFactories를 이용하여, PasswordEncoder를 쉽게 빈으로 등록할 수 있다.

다양한 패스워드 인코딩 방식을 지원하고, 어떠한 방식인지 패스워드 앞에 prefix를 붙여주면
prefix값에 따라 적절한 인코더를 적용한다.

@Configuration
public class SecurityConfiguration {
  @Bean
  public PasswordEncoder passwordEncoder() {
    return PasswordEncoderFactories.createDelegatingPasswordEncoder();
  }

PasswordEncoderFactories 가 제공하는 인코더들은 다음과 같다.

public class PasswordEncoderFactories {
    public static PasswordEncoder createDelegatingPasswordEncoder() {
        String encodingId = "bcrypt";
        Map<String, PasswordEncoder> encoders = new HashMap();
        encoders.put(encodingId, new BCryptPasswordEncoder());
        encoders.put("ldap", new LdapShaPasswordEncoder());
        encoders.put("MD4", new Md4PasswordEncoder());
        encoders.put("MD5", new MessageDigestPasswordEncoder("MD5"));
        encoders.put("noop", NoOpPasswordEncoder.getInstance());
        encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
        encoders.put("scrypt", new SCryptPasswordEncoder());
        encoders.put("SHA-1", new MessageDigestPasswordEncoder("SHA-1"));
        encoders.put("SHA-256", new MessageDigestPasswordEncoder("SHA-256"));
        encoders.put("sha256", new StandardPasswordEncoder());
        return new DelegatingPasswordEncoder(encodingId, encoders);
    }

    private PasswordEncoderFactories() {
    }
}

 

반응형

'Spring > Spring Security' 카테고리의 다른 글

스프링 시큐리티 아키텍처  (0) 2020.01.06
ExceptionTranslationFilter  (0) 2020.01.06
AccessDecisionManager  (0) 2019.12.12
Spring Security Architecture  (0) 2019.12.11
Spring Security OAuth2  (0) 2019.08.05