1. 개요

이 빠른 사용방법(예제)에서는 로그인한 사용자의 정보를 Thymeleaf에 표시하는 방법을 살펴보겠습니다 .

Thymeleaf 기사를 사용하여 Spring Security 에서 빌드한 프로젝트를 확장합니다 . 먼저 사용자 정보를 저장하는 사용자 정의 모델과 이를 검색하는 서비스를 추가합니다. 그런 다음 Thymeleaf Extras 모듈의 Spring Security Dialect를 사용하여 표시합니다.

2. UserDetails 구현

UserDetails는 Security과 관련되지 않은 사용자 정보를 보유하는 데 사용되는 Spring Security의 인터페이스입니다.

인증된 사용자 세부 정보를 저장하기 위한 모델로 일부 사용자 정의 필드를 사용하여 UserDetails 인터페이스 구현을 생성합니다 . 그러나 더 적은 수의 필드와 메서드를 처리하기 위해 기본 프레임워크 구현인 User 클래스 를 확장합니다 .

public class CustomUserDetails extends User {

    private final String firstName;
    private final String lastName;
    private final String email;

    private CustomUserDetails(Builder builder) {
        super(builder.username, builder.password, builder.authorities);
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.email = builder.email;
    }

    // omitting getters and static Builder class
}

3. UserDetailsService 구현

프레임워크의 UserDetailsService 단일 메서드 인터페이스는 인증 프로세스 중에 UserDetails를 가져오는 일을 담당합니다 .

결과적으로 CustomUserDetails를 로드할 수 있으려면 UserDetailsService  인터페이스를 구현해야 합니다 . 이 예에서는 사용자 이름을 키로 사용하는 에 사용자 세부 정보를 하드코딩하고 저장합니다 .

@Service
public class CustomUserDetailsService implements UserDetailsService {

    private final PasswordEncoder passwordEncoder;
    private final Map<String, CustomUserDetails> userRegistry = new HashMap<>();

    // omitting constructor

    @PostConstruct
    public void init() {
        userRegistry.put("user", new CustomUserDetails.Builder().withFirstName("Mark")
          .withLastName("Johnson")
          .withEmail("mark.johnson@email.com")
          .withUsername("user")
          .withPassword(passwordEncoder.encode("password"))
          .withAuthorities(Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER")))
          .build());
        userRegistry.put("admin", new CustomUserDetails.Builder().withFirstName("James")
          .withLastName("Davis")
          .withEmail("james.davis@email.com")
          .withUsername("admin")
          .withPassword(passwordEncoder.encode("password"))
          .withAuthorities(Collections.singletonList(new SimpleGrantedAuthority("ROLE_ADMIN")))
          .build());
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        CustomUserDetails userDetails = userRegistry.get(username);
        if (userDetails == null) {
            throw new UsernameNotFoundException(username);
        }
        return userDetails;
    }
}

또한 필요한 loadUserByUsername() 메서드를 구현하기 위해 사용자 이름으로 레지스트리 맵 에서 해당 CustomUserDetails 개체를  가져옵니다 . 그러나 사용자 세부 정보는 프로덕션 환경의 저장소에서 저장되고 검색됩니다.

4. 스프링 시큐리티 설정

먼저 CustomUserDetailsService 구현에 연결될 UserDetailsService를 Spring Security 구성에 추가해야 합니다 . 또한 해당 메서드를 통해 HttpSecurity 인스턴스 에 설정합니다 . 나머지는 사용자를 인증하고 /login , /logout/index Endpoints을 구성해야 하는 최소한의 Security 구성입니다.

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {

    private final UserDetailsService userDetailsService;

     // omitting constructor

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.userDetailsService(userDetailsService)
            .authorizeRequests()
            .anyRequest()
            .authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .permitAll()
            .successForwardUrl("/index")
            .and()
            .logout()
            .permitAll()
            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
            .logoutSuccessUrl("/login");
        return http.build();
    }
}

5. 로그인한 사용자 정보 표시

Thymeleaf Extras 모듈은 인증 객체 에 대한 액세스를 제공 하고 Security Dialect를 사용하여 로그인한 사용자 정보를 Thymeref 페이지에 표시할 수 있습니다.

CustomUserDetails 객체는 Authentication 객체의 principal 필드를 통해 액세스할 수 있습니다 . 예를 들어  sec:authentication=”principal.firstName”을 사용하여 firstName 필드에 액세스할 수 있습니다 .

<!DOCTYPE html>
<html xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<title>Welcome to Spring Security Thymeleaf tutorial</title>
</head>
<body>
    <h2>Welcome</h2>
    <p>Spring Security Thymeleaf tutorial</p>
    <div sec:authorize="hasRole('USER')">Text visible to user.</div>
    <div sec:authorize="hasRole('ADMIN')">Text visible to admin.</div>
    <div sec:authorize="isAuthenticated()">Text visible only to authenticated users.</div>
    Authenticated username:
    <div sec:authentication="name"></div>
    Authenticated user's firstName:
    <div sec:authentication="principal.firstName"></div>
    Authenticated user's lastName:
    <div sec:authentication="principal.lastName"></div>
    Authenticated user's email:
    <div sec:authentication="principal.lastName"></div>
    Authenticated user roles:
    <div sec:authentication="principal.authorities"></div>
</body>
</html>

또는 sec:authentication 속성 없이 Security Dialect 표현식을 작성하는 동등한 구문은 Spring Expression Language를 사용하는 것입니다. 따라서 더 편하다면 Spring Expression Language 형식을 사용하여 firstName 필드를 표시할 수 있습니다.

<div th:text="${#authentication.principal.firstName}"></div>

6. 결론

이 기사에서는 Spring Boot 애플리케이션에서 Spring Security의 지원을 사용하여 로그인한 사용자의 정보를 Thymeleaf에 표시하는 방법을 살펴보았습니다.

항상 그렇듯이 예제의 소스 코드는 GitHub에서 사용할 수 있습니다 .

res – Security (video) (cat=Security/Spring Security)