【问题标题】:How do I setup a valid on-premise ADFS URI?如何设置有效的本地 ADFS URI?
【发布时间】:2017-02-19 02:10:05
【问题描述】:

我有一个 .NET 4.6.2 Windows 客户端应用程序,它需要从我们的本地 ADFS 服务器获取身份验证令牌并使用它来调用 ASP.NET Core REST API。它的客户端名称、ID (GUID) 和重定向 URI 已在 ADFS 中注册。我正在使用最新的 ADAL (v3.13) 库来促进身份验证。我正在尝试获取一个令牌,如 ADAL 示例代码中所示:

AuthenticationContext authenticationContext = new AuthenticationContext("https://<adfs-sts-server>/<rest-api-host>", false);
var result = authenticationContext.AcquireTokenAsync(<rest-api-resource-uri>, clientId, redirectUri, new PlatformParameters(PromptBehavior.Auto));

AcquireTokenAsync 调用返回错误,说:基于浏览器的身份验证对话框未能完成。原因:服务器没有找到任何匹配请求的URI(统一资源标识符)。

谁能告诉我:

  1. 错误中引用的“请求的 URI”是 https://&lt;adfs-sts-server&gt;/&lt;rest-api-host&gt; 还是 &lt;rest-api-resource-uri&gt;
  2. 我是否需要以某种方式向 ADFS 注册 &lt;rest-api-host&gt;&lt;rest-api-resource-uri&gt;,如果需要,如何注册?
  3. 我需要任何其他信息才能使其正常工作?

谢谢! 彼得

【问题讨论】:

    标签: c# asp.net-core adfs adal


    【解决方案1】:

    使用 Active Directory 联合身份验证服务 (ADFS) 从 Windows 客户端为本地端点提供身份验证

    配置 ADFS

    配置 ADFS 有 2 个部分。

    向 ADFS 注册客户端应用程序

    ADFS 需要能够识别请求用户身份验证的应用程序,无论是服务、WPF 应用程序、Web 客户端还是 Office 插件。我已经通用并添加了以下客户端,我们可以将其用于大多数 C# 请求;我们可能需要为 Web 客户端注册一个具有不同回调的新客户端。

    使用现有的众多工具之一为客户端 ID 生成 GUID。
    * CLIENT_ID 和 APP_NAME 应该是唯一的。 * 对于 Web 客户端,重定向 URI 是身份验证服务在对用户进行身份验证后重定向您的呼叫的位置。它应该是一个端点,您可以在其中处理令牌并继续使用您的客户端应用程序。重定向 URI 并没有真正用于富客户端/服务/插件。

    CLIENT_ID = 26E54EC9-7988-4DAE-A527-483A8A78B1C6
    APP_NAME = Investplus
    DESCRIPTION = Invest+ rich client suite
    REDIRECT_URI = https://server/redirect-adfs.html
    
    客户注册说明

    (在向导中可能是可能的,但这是我在网上找到的,对我们有用)

    1. 以管理员身份登录 AD FS 服务器并打开 Windows PowerShell 命令窗口。
    2. 输入以下命令。在 Windows PowerShell 中

      Add-AdfsClient -ClientId &lt;CLIENT_ID&gt; -Name &lt;APP_NAME&gt; -RedirectUri &lt;REDIRECT_URI&gt;

    注册要访问的资源(ADFS 中的“依赖方”)

    我发现this link 很有用,它会引导您完成设置依赖方的向导步骤。

    信赖方注册说明

    服务器团队的管理员需要使用 ADFS 添加信赖方信任向导,并在“选择数据源”步骤下选择手动输入有关信赖方的数据 em>。

    您需要为此向导提供的值:

    DISPLAY_NAME                                      = "MyInvestApi" (Unique display name for this Relying party)
    PROFILE                                           = "AD FS Profile"
    ENABLE_SUPPORT_FOR_WS-FEDERATION_PASSIVE_PROTOCOL = true
    URL                                               = "https://server/api"  (Unique URL for this RP)
    ADD_ONE_OR_MORE_IDENTIFIERS                       = eg. "urn:myInvestApi" and "https://server/api"
    ACCEPT_REMAINING_DEFAULTS
    

    如果有机会,添加声明规则

    SEND_LDAP_ATTRIBUTES_AS_CLAIMS = true
    ATTRIBUTE_STORE                = Active Directory
    SELECT_USEFUL_ATTRIBUTES       = User-Principal-Name; Email; Display-Name
    

    配置/编码客户端应用程序

    Microsoft 为从 C# 到 Javascript,从 iOS 到 Cordova 再到 Node 的一系列平台和语言提供 Active Directory Authentication Libraries (ADAL)。

    在每个主要版本中公开的 API 都发生了显着变化:我使用的是最新的 C# 库,目前是 3.13.5。

    该库使编码非常简单,只需几行代码;我遇到的问题是:

    1. 我找不到用于 ADFS 的 URL 的解释 安全令牌服务 (STS)
    2. 我在这里找不到整个过程的文档(大多数文档都集中在 Azure FS),我努力解决 Client依赖方 提供给 ADFS 的值是如何映射的 到代码中使用的值。

    要在代码中使用的 ADFS 端点/URL 是什么?

    Microsoft 的最佳做法是将您的 ADFS/STS 服务器 URL 命名为 https://sts.domain.com(有些人使用 https://adfs.domain.com,请咨询您的服务器管理员)。但是,如果您尝试从浏览器中点击它,您将收到 404 - Not found 并尝试在代码中检索令牌,ADAL 库报告:

     The browser based authentication dialog failed to complete. Reason: The server has not found anything matching the requested URI (Uniform Resource Identifier).
    

    这就是我找到要使用的端点的方式:

    1. ADFS 在“https://sts.domain.com/federationmetadata/2007-06/federationmetadata.xml”发布联合元数据
      • 解压此文件并在文本编辑器中打开。
    2. 在配置依赖方时,我们在指定资源端点时指定了“启用对 WS-Federation Passive Protocol 的支持”,因此在 XML 中搜索PassiveRequestorEndpoint
    3. 使用此节点中的&lt;Address&gt; - 在我的情况下为https://sts.domain.com/adfs/ls/。我不知道这是否始终是该值,或者是否在设置 ADFS 时指定它,因此每个站点可能不同。

    在代码中还要使用哪些其他值?

    我们希望我们的客户端应用程序从 ADFS 检索 JSON Web 令牌 (JWT),我们可以将其传递给受保护的资源以进行身份​​验证/授权。

    在最简单的情况下,可以通过 3 行代码 + 配置来检索访问令牌,这将展示如何将我们在 ADFS 中配置的内容转换为 ADAL 所需的值:

    var stsEndpoint = "https://sts.domain.com/adfs/ls/";
    var relyingPartyIdentifier = "urn:myInvestApi";    // Tenant in Azure AD speak, but this is an on-premise service
    var authority = stsEndpoint + relyingPartyIdentifier;
    var restResourceUrl = "https://server/api";   
    var redirectUri = "https://server/redirect-adfs.html";
    const string CLIENT_ID = "26E54EC9-7988-4DAE-A527-483A8A78B1C6";
    
    AuthenticationContext authenticationContext = new AuthenticationContext(authority, false);
    var asyncRequest = authenticationContext.AcquireTokenAsync(restResourceUrl, CLIENT_ID, redirectUri, new PlatformParameters(PromptBehavior.Auto));
    var accessToken = asyncRequest.Result.AccessToken;
    

    有用的参考资料

    【讨论】:

    • 你好@Petter,请给我澄清一下“restResourceUrl”我如何从 ADFS 和“依赖方”获取这个 Url 谢谢,Ajay Dodiya
    • @ajaysinhrajput - restResourceUrl 是需要 ADFS 身份验证的 REST API(或网站)的 URL。依赖方标识符是您在 ADFS 中定义的 API 的唯一标识符。
    • 感谢您的快速回复。
    • 非常感谢。权威 URI 让我头疼。没有在文档中阅读任何内容,大部分信息是针对 Azure 的,几乎没有针对 AD FS。
    • 当我从我的 asp.netcore IdentityServer 驱动的 IdentityProvider 重定向到 ADFS 时,一切正常,除了我的服务器在请求的 url 的重定向 url 部分发送了错误的端口。端口应该是 5555(它正确配置为将传入请求路由到我的 IdentityProvider 的反向代理的端口),但我的 IdentityProvider 打开的 url 中的重定向 uri 端口实际上是我的 IdentityProvider 的侦听端口。此外,正确的端口 (5555) 在我的 IdentityProvider 的“.well-known/openid-configuration”中无处不在。有什么想法吗?
    【解决方案2】:

    要为 Web API 颁发令牌,我们需要通过为 Web API 创建依赖方信任来使 ADFS 能够识别它。当我们添加回复方时,我们需要指定回复方的标识符,如下图(Windows Server 2012 R2):

    然后我们可以使用这个标识符作为资源 URI 来获取这个回复方的令牌。请确保资源 URI 正确,如上图所示。

    这是一篇关于使用 OAuth 使用 ADFS 进行开发的文章:

    Developing Modern Applications using OAuth and Active Directory Federation Services

    【讨论】:

    • 谢谢,这可能正是我要找的,我会试试看。
    • 谢谢,这很有帮助,但结果只是故事的一部分——我将发布这个过程的完整描述,因为似乎没有太多全面的文档在那里使用 ADFS 为访问本地资源的 C# 客户端提供令牌。
    【解决方案3】:

    根据 asdf 的版本,您可能能够使用“发现”来获取要使用的端点。

    查看这篇文章了解更多详情:http://www.cloudidentity.com/blog/2015/08/21/openid-connect-web-sign-on-with-adfs-in-windows-server-2016-tp3/

    【讨论】:

    • 谢谢,我会记住这一点,但我的公司需要一段时间才能迁移到 Windows Server 2016。目前在 2012 R2
    猜你喜欢
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-19
    • 2017-01-27
    • 2014-02-27
    相关资源
    最近更新 更多