使用MSAL Python获取机密客户端令牌时无法设置preferred_username声明
守护程序应用中设置preferred_username声明不生效的问题解决
问题根源
你对client_claims参数的用途理解有误。这个参数的作用是向Azure AD声明客户端期望令牌中包含特定声明,或验证声明的取值,而非让客户端直接将自定义声明注入到令牌中。在客户端凭据流(守护程序模式)下,令牌的声明由Azure AD根据应用注册配置生成,客户端无法通过client_claims直接添加或修改声明。
正确实现方式
1. 理解守护程序流的声明特性
守护程序流是无用户上下文的认证方式,preferred_username属于用户相关的声明,默认不会出现在这类令牌中。即使你在应用注册中添加了该可选声明,Azure AD也不会为无用户的客户端凭据令牌生成这个值。
2. 方案一:使用自定义客户端断言注入声明
如果必须在令牌中加入preferred_username,可以通过客户端断言的方式,自行构造包含该声明的JWT并签名,然后将其作为客户端凭据传递给MSAL:
import jwt import time from msal import ConfidentialClientApplication def create_client_assertion(client_id, private_key, thumbprint): # 构造JWT payload,添加自定义声明 payload = { "aud": "https://login.microsoftonline.com/[你的租户ID]/v2.0", "iss": client_id, "sub": client_id, "exp": int(time.time()) + 3600, # 1小时有效期 "iat": int(time.time()), "preferred_username": "Test" # 自定义声明 } # 使用私钥签名JWT assertion = jwt.encode( payload, private_key, algorithm="RS256", headers={"x5t": thumbprint} ) return assertion # 构造客户端断言 client_assertion = create_client_assertion( config["client_id"], open(config['private_key_file']).read(), config["thumbprint"] ) # 初始化ConfidentialClientApplication,使用客户端断言作为凭据 app = ConfidentialClientApplication( config["client_id"], authority=config["authority"], client_credential=client_assertion ) # 获取令牌 result = app.acquire_token_for_client(scopes=config["scope"])
3. 方案二:通过企业应用声明映射添加自定义声明
如果你的自定义API是作为企业应用配置的,可以在Azure AD的企业应用设置中,添加声明映射规则,将某个固定值或应用属性映射到preferred_username声明。这种方式不需要修改代码,直接在Azure门户配置即可。
总结
client_claims无法用来注入自定义声明,它是客户端对Azure AD生成令牌的声明要求。- 守护程序流无用户上下文,如需添加用户相关声明,需通过客户端断言或企业应用声明映射实现。
内容的提问来源于stack exchange,提问作者Anon957
相关产品推荐
相关产品推荐

