Spring Security - CustomUserDetails

킹콩(King Kong)·2024년 12월 12일

Customizing UserDetails

  • 관리하고자 하는 사용자 속성을 추가할 수 있다.
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;

public class CustomUserDetails implements UserDetails {

    private String username;
    private String password;
    private boolean enabled;
    private boolean accountNonLocked;
    private boolean credentialsNonExpired;
    private boolean accountNonExpired;
    private Collection<? extends GrantedAuthority> authorities;

    // 생성자
    public CustomUserDetails(String username, String password, boolean enabled, 
                             boolean accountNonLocked, boolean credentialsNonExpired, 
                             boolean accountNonExpired, Collection<? extends GrantedAuthority> authorities) {
        this.username = username;
        this.password = password;
        this.enabled = enabled;
        this.accountNonLocked = accountNonLocked;
        this.credentialsNonExpired = credentialsNonExpired;
        this.accountNonExpired = accountNonExpired;
        this.authorities = authorities;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
        return accountNonExpired;
    }

    @Override
    public boolean isAccountNonLocked() {
        return accountNonLocked;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return credentialsNonExpired;
    }

    @Override
    public boolean isEnabled() {
        return enabled;
    }
}

CustomUserDetailsService

import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class CustomUserDetailsService implements UserDetailsService {

    private final UserRepository userRepository; // 사용자 정보를 가져오는 리포지토리

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

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 데이터베이스에서 사용자 정보 조회
        UserEntity user = userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("User not found: " + username));

        // CustomUserDetails 생성 및 반환
        return new CustomUserDetails(
                user.getUsername(),
                user.getPassword(),
                user.isEnabled(),
                !user.isAccountLocked(),       // 계정 잠김 여부 반영
                !user.isCredentialsExpired(),  // 비밀번호 만료 여부 반영
                true,                          // 계정 만료 여부 (예제에서는 항상 활성화)
                List.of(new SimpleGrantedAuthority("ROLE_USER")) // 예제 권한
        );
    }
}

SecurityContextHolder 에서 Authentication 가져오기

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

    @GetMapping("/profile")
    public String getProfile(Model model) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();
        model.addAttribute("user", userDetails);
        return "profile";
    }
}
  • thymeleaf 화면에서 처리
<p>Username: <span th:text="${user.username}"></span></p>
<p>Custom Field: <span th:text="${user.customField}"></span></p>
<p>Authorities: <span th:text="${user.authorities}"></span></p>
profile
IT를 쉽게 이해해 보아요~😄

0개의 댓글