Thymeleaf获取已认证AD用户全名的技术实现问题
解决Active Directory认证后在Thymeleaf中获取用户全名的问题
问题根源
默认的org.springframework.security.ldap.userdetails.LdapUserDetailsImpl只封装了用户名、角色这类基础认证属性,并没有从AD中提取用户全名、邮箱等扩展信息,所以直接调用getUser()会报错。要获取这些信息,我们需要自定义UserDetails并配置属性映射。
解决方案步骤
1. 创建自定义UserDetails实现类
先定义一个类,继承LdapUserDetailsImpl来扩展属性,用来存储AD中的额外信息:
import org.springframework.security.ldap.userdetails.LdapUserDetailsImpl; import org.springframework.security.core.GrantedAuthority; import java.util.Collection; public class CustomLdapUserDetails extends LdapUserDetailsImpl { private String fullName; private String firstName; // 可根据需求添加更多AD属性,比如邮箱、部门等 // Getter & Setter public String getFullName() { return fullName; } public void setFullName(String fullName) { this.fullName = fullName; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } }
2. 实现UserDetailsContextMapper接口
这个接口负责把AD返回的上下文信息映射到我们的自定义UserDetails对象中:
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.ldap.userdetails.UserDetailsContextMapper; import org.springframework.ldap.core.DirContextAdapter; import org.springframework.ldap.core.DirContextOperations; import org.springframework.security.core.GrantedAuthority; import java.util.Collection; public class CustomLdapUserDetailsContextMapper implements UserDetailsContextMapper { @Override public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) { CustomLdapUserDetails user = new CustomLdapUserDetails(); // 填充基础认证信息 user.setUsername(username); user.setAuthorities(authorities); // 从AD上下文提取属性,注意属性名要和你的AD配置一致,比如全名可能是displayName或cn String fullName = ctx.getStringAttribute("displayName"); String firstName = ctx.getStringAttribute("givenName"); user.setFullName(fullName); user.setFirstName(firstName); return user; } @Override public void mapUserToContext(UserDetails user, DirContextAdapter ctx) { // 若无需修改AD用户信息,此方法可空实现 } }
提示:AD中的属性名可能因域配置不同有差异,你可以通过AD管理工具(比如Active Directory用户和计算机)查看用户属性的具体名称。
3. 给AuthenticationProvider绑定自定义Mapper
修改你的activeDirectoryLdapAuthenticationProvider Bean,添加自定义的上下文映射器:
@Bean public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() { ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(adDomain, adUrl); provider.setConvertSubErrorCodesToExceptions(true); provider.setUseAuthenticationRequestCredentials(true); // 关键:设置自定义的UserDetails上下文映射器 provider.setUserDetailsContextMapper(new CustomLdapUserDetailsContextMapper()); return provider; }
4. 在Thymeleaf中获取用户全名
现在你可以在页面中直接调用自定义属性了:
<!-- 显示用户全名 --> <span th:text="${#authentication.principal.fullName}"></span> <!-- 显示用户名字 --> <span th:text="${#authentication.principal.firstName}"></span>
补充说明
如果需要获取更多AD属性,只需要在CustomLdapUserDetails中添加对应字段,然后在mapUserFromContext方法里从DirContextOperations提取对应的属性值即可。
内容的提问来源于stack exchange,提问作者Somebody




