You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动