使用 ADAL 从 UWP 中的 ADFS 获取 UserInfo
Posted
技术标签:
【中文标题】使用 ADAL 从 UWP 中的 ADFS 获取 UserInfo【英文标题】:Get UserInfo from ADFS in UWP with ADAL 【发布时间】:2017-10-12 17:23:43 【问题描述】:我正在尝试使用 ADFS 对用户进行身份验证,并且我正在使用 ADAL。身份验证似乎有效,因为我可以获得 AccessToken。问题是查看代码authResult
包含一个UserInfo
,其中所有属性(例如GivenName
或FamilyName
)都是null
。
AuthenticationContext authContext = null;
AuthenticationResult authResult;
try
authContext = new AuthenticationContext(authority, false);
authResult = await authContext.AcquireTokenAsync(resource, clientId, new Uri(returnUri),
new PlatformParameters(PromptBehavior.Auto, false));
由于 ADFS 配置,这些值为空?我注意到解码返回的 AccessToken 我可以读取用户信息。但我不认为解码 JWT Token 是获取这些信息的正确方法。你有更好的建议吗?
我也看到人们通过使用声明来获取信息,但我不知道如何在 UWP 上使用它,因为我发现的所有示例都使用过
ClaimsPrincipal claimsPrincipal = System.Threading.Thread.CurrentPrincipal as ClaimsPrincipal;
但System.Threading.Thread
在 UWP 上不可用。
【问题讨论】:
【参考方案1】:通常,access_token
用于 Oauth 和 OpenID 连接方案,并打算由资源使用。为了识别用户,我们应该使用id_token
(验证令牌并通过解码令牌来提取与用户相关的声明)。代币的使用请参考以下:
id_token:用于表示用户身份的 JWT 令牌。这 id_token 的“aud”或受众声明与 本机或服务器应用程序。 access_token:用于 Oauth 和 OpenID 连接场景的 JWT 令牌 并打算被资源消耗。 “听众”或观众 此令牌的声明必须与资源或 Web 的标识符匹配 API。 refresh_token:提交此令牌代替收集用户 凭据以提供单点登录体验。这个令牌是 由 AD FS 发布和使用,客户端不可读 或资源。
关于 ADFS 的本地客户端到 Web API 场景,您可以参考以下链接:
AD FS Scenarios for Developers - Native client to Web API
【讨论】:
您能否帮助了解我如何获取 id_token 并提取声明?id_token
应该可以通过authResult
对象(authResult.IdToken
) 作为您共享的代码获取。要从令牌中提取声明,您可以使用System.IdentityModel.Tokens.Jwt
。这是一个similar thread 供您参考。
idtoken 仅在 ADFS 2016 中可用。请检查版本。【参考方案2】:
取决于您的服务器的 ADFS 版本。如果您的公司使用的是 Windows Server 2012 R2,那么它是 ADFS 3.0。我确实成功地与我工作的公司的管理员创建的 SSO 登录集成。你应该在冒险之前参考这篇文章:https://docs.microsoft.com/en-us/previous-versions/adfs-windows-server-2012r2/dn660968(v=msdn.10)。注意:你甚至不需要制作 ToDoList 的 web api。
仅使用 GetAuthorizationHeader() 和 authenticationContext.AcquireTokenAsync(),您可以通过要求用户授权其凭据并解密接收令牌来获取令牌。
这是我做的代码示例:
authority = https://contoso.com/adfs/ls(来自 ADFS 元数据的端点)
resourceURI = https://localhost:44300/(依赖方,请您的 ADFS 管理员注册)
clientID = 建议使用 Package.appmanifest 在 Packaging 标签中的包名。只要是唯一的 ID。
clientReturnURI = 使用以下代码获取clientReturnURI(也可以在文章中的链接中找到):
string clientReturnURI = string.Format("ms-appx-web://Microsoft.AAD.BrokerPlugIn/0",WebAuthenticationBroker.GetCurrentApplicationCallbackUri().Host.ToUpper());
AuthenticationContext ac = new AuthenticationContext(Authority_Uri, false); AuthenticationResult ar = await ac.AcquireTokenAsync(resourceURI, GlobalVar.clientID, new Uri(clientReturnURI), new PlatformParameters(PromptBehavior.Always, true));
var jwt = new JwtSecurityToken(ar.AccessToken);
string unique_name = jwt.Claims.First(c => c.Type == JwtRegisteredClaimNames.UniqueName).Value;
您可以将 JwtRegisteredClaimNames.UniqueName 替换为其他任何内容。这取决于访问令牌中可用的信息/声明。您应该通过在 var jwt 处放置断点来检查 jwt 中的可用信息。或者您可以在本网站的 AuthenticationResult.AccessToken 中解密访问令牌: https://jwt.ms/
最后,您需要从 ADFS 管理员处安装证书,并在您的 Web 和 UWP 服务器上安装该证书,以允许应用程序能够信任地执行操作。
【讨论】:
以上是关于使用 ADAL 从 UWP 中的 ADFS 获取 UserInfo的主要内容,如果未能解决你的问题,请参考以下文章
如何从本地 SharePoint 2013 和 ADFS 获取 FedAuth Cookie
未从 ADFS 3.0 获取用于 OAuth2 访问令牌的 JWT 中的用户身份
共享点身份验证。如何从 ADFS 获取 SharePoint cookie
如何从 UWP(又名 .NET Core)中的 Type 对象获取程序集