multiply authentication
- springsecurity provide multiply authentication by using multipleAthentication
interface AuthenticationProvider
- supports method tell to spring seciruty what kind of authentication method do I need.
Implementing and Customising the AuthenticationProvider inside our application
- create class implements AuthenticationProvider interface
- process
- user enter Id, password
- spring security made Authentication object
- there are principal(user identification information) and Credentials(authentication token, password) in Authentication object
- Authentication object injected into authenticate method(parameter)
- can make custom authenticate logic in authenticate method
- if success authenticate method return Authentication object
- if error authenticate method return AuthenticationError
- supports method show what kind of token in authentication object
package com.eazybytes.config;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.eazybytes.model.Customer;
import com.eazybytes.repository.CustomerRepository;
@Component
public class EazyBankUsernamePwdAuthenticationProvider implements AuthenticationProvider {
@Autowired
private CustomerRepository customerRepository;
@Autowired
private 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));
}
}
- spring security에 인증 인가를 위한 custom Authentication을 인식하도록 하기 위해서는 @Component 어노테이션이 필요하다
- grantedAuthority는 사용자가 가지는 권한(역할)을 나타내는 인터페이스이다.
- 예를들어서 ROLE_ADMIN, ROLE_USER 등
- grantedAutority는 단순히 역할을 표현하는 것이며 권한을 부여하거나 제어하는 것은 아니다.
- 보통 데이터베이스나 설정파일에서 역할이 정의되며, Spring security는 이러한 역할을 기반으로 인증, 인가를 처리한다.
- 이 역할 정보는 인증 이후에 authentication객체 내에서 사용자의 권한 정보를 나타내는 역할로 활용된다.
- 해당 코드가 실행 된 결과, authentication안의 usernamepasswordauthenticationtoken에 authorities가 포함되어 있고, authorities에 role이 저장되어 있다.
- BadCredentialsException은 Spring Security에서 사용되는 예외클래스 중 하나로, 인증 과정에서 비밀번호가 잘못된 경우에 발생한다.
- 기존에 인증, 인가 과정이 없는 class를 삭제해준다.
Spring security 인증과정
- 사용자가 보호된 리소스에 접근하려고 시도한다.
- SecurityFilterChain이 실행된다.
- UsernamePasswordAuthenticationToken이 생성된다.
- AuthenticationManger가 등록된 AuthenticationProvider를 차례대로 실행해서 인증을 시도한다.
- AuthenticationProvider는 사용자 인증 정보를 확인하고, 인증에 성공하면 Authentication객체를 반환한다.
- 인증 과정에서 사용자 정보가 필요할 때 UserDetailsService를 호출하여 실제 사용자 정보를 가져온다.
- 가져온 사용자 정보돠 인증 정보(비밀번호) 등을 비교하여 인증이 성공했는지 여부를 확인한다.
- 인증에 성공하면 Authentication 객체가 생성되어 인증 결과를 담고, 이는 SecurityContextHolder에 저장된다.