비밀번호는 암호화되어(▼) DB에 저장되어있음. 근데 같은 문자열을 암호화하더라도 인코딩된 값이 다르기때문에 이 역시 암호화해서 DB의 값을 비교하고.. 이렇게 수동적이게 말고 스프링시큐리티를 이용해야함.
- MemberAuthenticationProvider
- 원하는 것
스프링 시큐리티를 사용해서 사용자의 아이디와 비밀번호를 검증
- 구현 방법
AuthenticationProvider 인터페이스를 구현하는 클래스 생성
주입 받고
authenticate 메서드
UserDetails userDetails = userService.loadUserByUsername(username);
userService를 통해 사용자 정보 가지고와서,
if (userDetails != null && passwordEncoder.matches(password, userDetails.getPassword()))
return new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities());
else
return null;
사용자의 비밀번호와 사용자가 입력한 비밀번호를 비교해서 인증 수행
인증이 성공하면 UsernamePasswordAuthenticationToken 반환, 실패하면 null 반환
UsernamePasswordAuthenticationToken
기본동작은 아이디와 비밀번호로 사용자를 인증하는 것
인증에 성공하면 Authenticated를 true로 설정하고 사용자에게 해당 권한을 부여함
Authentication 객체에는 사용자의 인증 정보와 권한 정보가 포함되어 있음.
ㄴ 인증이 성공한 후에 스프링시큐리티에 의해 생성됨.
ㄴ 컨트롤러에서 이 정보를 검색하거나 사용할 수 있음.
ㄴ -> 현재 로그인한 사용자의 정보를 액세스하고 사용자 지정 로직 수행 가능(ex. 특정 사용자에게 기능을 허용/거부)
getPrincipal() : 사용자의 주요 정보를 반환 (주로 사용자 아이디, 이메일 또는 사용자의 고유 식별자와 관련된 정보)
getCredentials() : 사용자의 자격 증명(ex. 비밀번호) 반환
getAuthorities() : 사용자의 권한 목록 반환 (사용자에게 부여된 권한과 역할 나타냄)
supports 메서드
- AuthenticationProvider 인터페이스의 일부
- 파라미터로 받은 authentication클래스가 해당 AuthenticationProvider에서 처리 가능한 유형인지 판단
- authentication: 인증을 시도하는 사용자가 제출한 자격 증명 정보와 함께 생성된 Authentication 객체의 클래스
- 해당 AuthenticationProvider가 어떤 유형의 Authentication 객체를 지원하는지 나타내는 메서드(판단하는 역할)
- 해당 코드에서는 UsernamePasswordAuthenticationToken 클래스를 지원하도록 설정되어 있음
-> 사용자의 아이디와 비밀번호를 포함하는 토큰을 처리할 수 있음을 나타냄.
이러한 AuthenticationProvider를 스프링시큐리티 설정에 등록하고 사용하면,
스프링시큐리티가 사용자의 인증을 이 프로바이더를 통해서 처리하게 됨.
-> 이를 통해 사용자의 아이디&비번을 확인하고, 인증 성공하면 원하는 처리를 할 수 있게끔 구현할 수 있음.
더보기
package co.kr.lotte.security;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
@Log4j2
@Component
public class MemberAuthenticationProvider implements AuthenticationProvider {
@Autowired
private SecurityUserService userService; // 사용자 정보를 제공하는 서비스
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = authentication.getCredentials().toString();
// 사용자 정보 검색
UserDetails userDetails = userService.loadUserByUsername(username);
// 인증 성공 혹은 실패 시
if (userDetails != null && passwordEncoder.matches(password, userDetails.getPassword()))
return new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities());
else
return null;
}
@Override
public boolean supports(Class<?> authentication) {
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
}
[비밀번호 확인] 버튼을 눌렀을 때 컨트롤러로 사용자가 입력한 비밀번호를 전송해서 거기서 인증을 성공하면 다음 페이지로 이동시켜주고, 인증 실패라면 비밀번호가 일치하지 않다는 알림창을 띄워줌!
그리고 컨트롤러.
String으로 반환할거라 @ResponseBody 어노테이션 달아주고
토큰 생성해서 인증받기