Spring/spring secutiry

spring security 6.1 mysql authentication(개정 생성, login)

slow333 2023. 6. 11. 22:58

기본 순서

db생성(entity)-> repo구성->service 구성 -> security config 구성

entity (db 생성) : Many to Many

@Data
@Entity
@Table(name = "users", uniqueConstraints = {

@UniqueConstraint(columnNames = {"username"}),
@UniqueConstraint(columnNames = {"email"})
})
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)

private long id;
private String name;
private String username;
@Email
private String email;

private String password;

@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL )
@JoinTable(name = "user_roles",
joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id")
)
private Set<Role> roles;
}
@Getter @Setter
@Entity
@Table(name = "roles")

public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)

private long id;
@Column(length = 60)
private String name;
}

repository 생성

public interface UserRepository extends JpaRepository<User, Long> {

Optional<User> findByEmail(String email);
Optional<User> findByUsernameOrEmail(String username, String email);
Optional<User> findByUsername(String username);
Boolean existsByUsername(String username);
Boolean existsByEmail(String email);
}
public interface RoleRepository extends JpaRepository<Role, Long> {
Optional<Role> findByName(String name);
}

service 생성(UserDetailsService를 상속함)

@Service
public class CustomUserDetailsService implements UserDetailsService {


private final UserRepository userRepository;

public CustomUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}

@Override
public UserDetails loadUserByUsername(String usernameOrEmail) throws UsernameNotFoundException {

User user = userRepository.findByUsernameOrEmail(usernameOrEmail,usernameOrEmail)
.orElseThrow(() ->
new UsernameNotFoundException("User not found with username or email: "+usernameOrEmail)
);
return new org.springframework.security.core.userdetails
.User(user.getEmail(), user.getPassword(),mapRolesToAuthorities(user.getRoles()));

}
private Collection<? extends GrantedAuthority> mapRolesToAuthorities(Set<Role> roles){
return roles.stream().map(role -> new SimpleGrantedAuthority(role.getName())).toList();
}
}
 

SecurityConfig 구성

이전에는 WebScerurityConfigurerAdapter를 상속해서 사용

public class SecurityConfig extends WebScerurityConfigurerAdapter {

@Override

protected void configure(AuthenticationManagerBuilder auth) throws Exception {

auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());

}

 

이러한 방식이 다음과 같이 변경됨

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }

 

==> passwordEncoder가 기본으로 설정되어 있음

https://stackoverflow.com/questions/72381114/spring-security-upgrading-the-deprecated-websecurityconfigureradapter-in-spring

 

Spring Security: Upgrading the deprecated WebSecurityConfigurerAdapter in Spring Boot 2.7.0

I am trying to update the WebSecurityConfigurerAdapter as it has been deprecated. The class is configured as follows: @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = ...

stackoverflow.com

참고로 password encoding 값을 알기 위해 method 생성해서 확인함

DB에 임의로 개정 생성시 password에 대한 encoding 값을 알아야 함....


public class PasswordEncoderGenerator {
public static void main(String[] args) {
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
System.out.println(passwordEncoder.encode("pass"));
}
}
다음과 같은 값이 나오면 db의 password 에 붙여 넣음

$2a$10$yReRf4Lhb7GKNo/dk5fQ7uOFejzIxfHibVh79gTXojDuqVsOtEHvq