본문 바로가기
Spring/Security

Authentication 메커니즘

by y.j 2022. 6. 11.
728x90

인증 ( Authentication )

Authetication은 인증된 결과만 저장하는 것이 아니고, 인증을 하기 위한 정보와 인증을 받기 위한 정보가 하나의 객체에 동시에 들어있다. 인증을 제공해 줄 제공자(AuthenticationProvider)가 어떤 인증에 대해서 허가를 내줄 것인지 판단하기 위해서는 직접 입력된 인증을 보고 허가된 인증을 내주는 방식이기 때문이다.

AuthenticationProvider는 처리 가능한 Authentication에 대해 알려주는 support 메소드를 지원하고, authentication()에서 Authentication을 입력값과 출력밧으로도 사용한다.

  • Credentials : 인증을 받기 위해 필요한 정보, 비번등 (input)
  • Principal : 인증된 결과. 인증 대상 (output)
  • Details : 기타 정보, 인증에 관여된 된 주변 정보들
  • Authorities : 권한 정보들

Authentication을 구현한 객체들은 일반적으로 Token 이라는 이름의 객체로 구현된다. Token객체는 SecurityContextHolder 를 통해 세션이 있건 없건 언제든 접근할 수 있도록 필터체인에서 보장해 준다.


StudentAuthenticationToken

StudentAuthenticationToken class는 Authentication을 상속받은 Token객체이다. 

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class StudentAuthenticationToken implements Authentication {

    private Student principal;
    private String credentials;
    private String details;
    private boolean authenticated;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return principal == null ? new HashSet<>() : principal.getRole();
    }

    @Override
    public String getName() {
        return principal == null ? "" : principal.getUsername();
    }

}

Lombok이 없이는 이 모든 메서드를 구현해야 한다.

 

 

 

 


인증 제공자 ( AuthenticationProvider )

인증 제공자 ( AuthenticationProvider )는 기본적으로 Authentication을 받아서 인증을 하고 결과를 다시 Authentcation 객체로 전달합니다. supports()메서드를 재정의하여 어떤 인증인지 확인해주고 여러개 인증을 받을 수도 있습니다.

 

인증 관리자(AuthenticationManager)

인증 제공자들을 관리하는 인터페이스가 AuthenticationManager (인증 관리자)이고, 이 인증 관리자를 구현한 객체가 ProviderManager 입니다. 개발자가 직접 AuthenticationManager를 정의해서 제공하지 않는다면, AuthenticationManager 를 만드는 AuthenticationManagerFactoryBean에서 DaoAuthenticationProvider를 기본 인증제공자로 등록한 AuthenticationManager를 만든다. DaoAuthenticationProvider는 반드시 1개의 UserDetailsService 를 발견할 수 있어야 한다. 만약 없으면 InmemoryUserDetailsManager에 [username=user, password=(서버가 생성한 패스워드)]인 사용자가 등록되어 제공된다.


StudentManager

supports()에서 어떤 인증인지 Overriding을 하고 autheticationI()메서드는 authenticated에 true값을 넣어 return해준다.

@Component
public class StudentManager implements AuthenticationProvider, InitializingBean {

    private HashMap<String, Student> studentDB = new HashMap<>();

    @Override
    public void afterPropertiesSet() throws Exception {
        Set.of(
                new Student("hong", "홍길동", Set.of(new SimpleGrantedAuthority("ROLE_STUDENT"))),
                new Student("kang", "강아지", Set.of(new SimpleGrantedAuthority("ROLE_STUDENT"))),
                new Student("rang", "호랑이", Set.of(new SimpleGrantedAuthority("ROLE_STUDENT")))
        ).forEach(s->
            studentDB.put(s.getId(), s)
        );
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authentication;
        if(studentDB.containsKey(token.getName())) {
            Student student = studentDB.get(token.getName());
            return StudentAuthenticationToken.builder()
                    .principal(student)
                    .details(student.getUsername())
                    .authenticated(true)
                    .build();
        }
        return null; // 내가 처리 할 수 없는 authentication은 null로 넘겨야 한다.
                     // 조작을 하면 안되기 때문에..
    }

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

 

728x90

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

기본 실습  (0) 2022.06.05
폼 로그인  (0) 2022.05.30
SpringSecurity구조  (0) 2022.05.30
Spring Security  (0) 2022.05.30

댓글