이 영역을 누르면 첫 페이지로 이동
시간의화살 블로그의 첫 페이지로 이동

시간의화살

페이지 맨 위로 올라가기

시간의화살

행복하세요

[Spring Security6] 사용자 인증

  • 2023.08.06 10:45
  • Spring/Spring Security

 

 

 

스프링 시큐리티의 AuthenticationProvider는 사용자가 로그인 할 때 아이디와 비밀번호를 검증하는 역할을 수행한다.

 

기본적으로 DaoAuthenticationProvider 구현체를 사용해 데이터베이스에서 사용자 정보를 조회한 후 제공된 자격을 검증하는데, 기본 구현체가 요구사항을 충족시키지 못하는 경우 해당 인터페이스를 직접 구현해 맞춤형 검증 로직을 작성할 수 있다.

 

 

public interface AuthenticationProvider {

	Authentication authenticate(Authentication authentication) throws AuthenticationException;

	boolean supports(Class<?> authentication);

}

 

 

authenticate : 인증 요청을 처리한다. 인증에 성공한다면 Authentication 객체를 반환하고 실패하면 예외를 던진다.

supports : AuthenticationProvider가 특정 인증 유형을 제공하는지 판단한다. 

 

AuthenticationProvider 목록은 AuthenticationManager가 관리하고, 사용자로부터 인증 요청이 들어오면 AuthenticationManager는 등록된 AuthenticationProvider 목록을 순회하며 인증을 시도한다.

 

보통 하나의 AuthenticationProvider를 사용해도 충분하지만, 요구사항에 따라 여러 Provider를 사용할 수도 있다.

(SNS 로그인과 아이디, 비밀번호를 통한 로그인을 구현하려면 두 가지 Provider를 구현한다)

 

이 과정에서 supports 메서드를 사용해 해당 인증 요청을 처리할 수 있는지를 판단한다.

 

 

 

Authentication 객체는 현재 인증된 사용자의 세부 정보를 나타낸다.

 

public interface Authentication extends Principal, Serializable {

	Collection<? extends GrantedAuthority> getAuthorities();

	Object getCredentials();

	Object getDetails();

	Object getPrincipal();

	boolean isAuthenticated();

	void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;

}

 

 

Principal : 현재 인증된 사용자를 나타낸다. 일반적으로 User객체를 넣는다.

Credentials : 보통 비밀번호를 의미한다. 인증된 후에는 보안을 위해 제거된다.

Authorities : 사용자에게 부여된 권한이다.

Details : 인증 관련 추가 세부 정보를 저장한다. (IP주소, 세션ID 등)

Authenticated : 인증 여부를 나타내는 값이다.

 

보통 Authenticate 객체는 SecurityContextHolder를 통해 애플리케이션 전반에서 접근할 수 있다.

 

 

@Component
public class UsernamePwdAuthenticationProvider implements AuthenticationProvider {


    private final CustomerRepository customerRepository;
    private final PasswordEncoder passwordEncoder;

    public UsernamePwdAuthenticationProvider(CustomerRepository customerRepository, PasswordEncoder passwordEncoder) {
        this.customerRepository = customerRepository;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String pwd = authentication.getCredentials().toString();

        List<Customer> customer = customerRepository.findByEmail(username);
        
        if (customer.size() > 0) {
            if (passwordEncoder.matches(pwd, customer.get(0).getPwd())) {
                List<GrantedAuthority> authorities = new ArrayList<>();
                authorities.add(new SimpleGrantedAuthority(customer.get(0).getRole()));
                return new UsernamePasswordAuthenticationToken(username, pwd, authorities);
            } else {
                throw new BadCredentialsException("Invalid password!");
            }
        } else {
            throw new BadCredentialsException("No user registered with this details!");
        }
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
    }
}


	public UsernamePasswordAuthenticationToken(Object principal, Object credentials,
			Collection<? extends GrantedAuthority> authorities) {
		super(authorities);
		this.principal = principal;
		this.credentials = credentials;
		super.setAuthenticated(true); // must use super, as we override
	}

 

 

이메일을 아이디로 사용하는 예시이다.

 

데이터베이스에서 정보를 가져오고 사용자가 입력한 정보와 비교해 일치하는지 확인한다.

 

 

 

 

 

 

 

 

 

반응형
저작자표시 (새창열림)

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

[Spring Security6] Authorization과 Filter  (0) 2023.08.09
[Spring Security6] CORS, CSRF  (0) 2023.08.08
[Spring Security6] Password Encoder  (0) 2023.08.05
[Spring Security6] 주요 구성요소  (0) 2023.08.04
[Spring Security6] 내부 흐름  (0) 2023.07.30

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [Spring Security6] Authorization과 Filter

    [Spring Security6] Authorization과 Filter

    2023.08.09
  • [Spring Security6] CORS, CSRF

    [Spring Security6] CORS, CSRF

    2023.08.08
  • [Spring Security6] Password Encoder

    [Spring Security6] Password Encoder

    2023.08.05
  • [Spring Security6] 주요 구성요소

    [Spring Security6] 주요 구성요소

    2023.08.04
다른 글 더 둘러보기

정보

시간의화살 블로그의 첫 페이지로 이동

시간의화살

  • 시간의화살의 첫 페이지로 이동

검색

방문자

  • 전체 방문자
  • 오늘
  • 어제

카테고리

  • 분류 전체보기 (607)
    • Algorithm (205)
      • Data Structure (5)
      • Theory && Tip (33)
      • Baekjoon (166)
      • ALGOSPOT (1)
    • Spring (123)
      • Spring (28)
      • Spring Web MVC (20)
      • Spring Database (14)
      • Spring Boot (6)
      • Spring 3.1 (11)
      • Spring Batch (6)
      • Spring Security (16)
      • JPA (12)
      • Spring Data JPA (5)
      • QueryDSL (4)
      • eGovFramework (1)
    • Programming Language (74)
      • Java (19)
      • JavaScript (15)
      • C (25)
      • C++ (12)
      • Python (1)
      • PHP (2)
    • Computer Science (69)
      • Operating System (18)
      • Computer Network (17)
      • System Programming (22)
      • Universial Programming Lang.. (8)
      • Computer Architecture (4)
    • Database (21)
      • Database (7)
      • MySQL (3)
      • Oracle (3)
      • Redis (5)
      • Elasticsearch (3)
    • DevOps (20)
      • Docker && Kubernetes (8)
      • Jenkins (4)
      • Github Actions (0)
      • Amazon Web Service (8)
    • Machine Learning (28)
      • AI Introduction (28)
    • Mobile (28)
      • Android (21)
      • Flutter (7)
    • Solutions (14)
    • Life Logs (0)
    • 낙서장 (25)

최근 글

나의 외부 링크

메뉴

  • 홈

정보

13months의 시간의화살

시간의화살

13months

블로그 구독하기

  • 구독하기
  • RSS 피드

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. Copyright © 13months.

티스토리툴바