1. 概述
在本快速教程中,我們將探討如何在Thymeleaf中顯示已登錄用户的個人信息。
我們將擴展我們在 Spring Security 與 Thymeleaf 文章中構建的項目。首先,我們將添加自定義模型來存儲用户信息以及檢索服務。之後,我們將使用 Spring Security 語法的 Thymeleaf Extras 模塊顯示它們。
2. UserDetails 實現
UserDetails 是 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 接口。 在我們的示例中,我們將硬編碼和存儲用户詳細信息到具有用户名作為鍵的 Map 中:
@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("[email protected]")
.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("[email protected]")
.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() 方法,我們從註冊表 Map 中通過用户名獲取相應的 CustomUserDetails 對象。 但是,在生產環境中,用户詳細信息將存儲和從倉庫檢索。
4. Spring Security 配置
首先,我們需要在 Spring Security 的配置中添加 UserDetailsService,它將與 CustomUserDetailsService 實現進行關聯。 此外,我們將在 HttpSecurity 實例上通過相應的設置方法進行配置。 其餘的配置只是最小的安全配置,只需要驗證用户身份並配置 /login、/logout 和 /index 端點:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
private final UserDetailsService userDetailsService;
// omitting constructor
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.userDetailsService(userDetailsService)
.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry
.anyRequest().authenticated())
.formLogin(httpSecurityFormLoginConfigurer -> httpSecurityFormLoginConfigurer
.loginPage("/login").permitAll()
.defaultSuccessUrl("/index"))
.logout(httpSecurityLogoutConfigurer -> httpSecurityLogoutConfigurer.permitAll()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login"));
return http.build();
}
}
5. 顯示登錄用户的信息
Thymeleaf Extras 模塊提供對 Authentication 對象的訪問,以及藉助 Security Dialect,可以在 Thymeleaf 頁面上顯示登錄用户的信息。
CustomUserDetails 對象可通過 principal 字段在 Authentication 對象中訪問。例如,我們可以使用 sec:authentication=”principal.firstName” 訪問 firstName 字段:
歡迎使用 Spring Security Thymeleaf 教程
歡迎
Spring Security Thymeleaf 教程
用户可見文本。
管理員可見文本。
僅對已認證用户可見的文本。
已認證用户名:
已認證用户的 firstName:
已認證用户的 lastName:
已認證用户的 email:
已認證用户角色:
或者,在不使用 sec:authentication 屬性的情況下,編寫 Security Dialect 表達式的等效語法是使用 Spring Expression Language。因此,如果更習慣使用它,我們可以使用 Spring Expression Language 格式顯示 firstName 字段:
<div th:text="${#authentication.principal.firstName}"></div>
6. 結論
在本文中,我們看到了如何使用 Thymeleaf 在 Spring Boot 應用程序中,藉助 Spring Security 的支持,顯示已登錄用户的個人信息。