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에서 사용할 수 있습니다 .