c# - 如何设置有效的本地ADFS URI?

标签 c# asp.net-core adfs adal

我有一个.NET 4.6.2 Windows客户端应用程序,该应用程序需要从我们的本地ADFS服务器获取身份验证 token ,然后使用它来调用ASP.NET Core REST API。它的客户端名称,ID(GUID)和重定向URI已在ADFS中注册。我正在使用最新的ADAL(v3.13)库来简化身份验证。我正在尝试获取 token ,如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(统一资源标识符)匹配的任何内容。

谁能告诉我:
  • 错误中是否引用了https://<adfs-sts-server>/<rest-api-host><rest-api-resource-uri>中的“请求的URI”?
  • 我是否需要以某种方式向ADFS注册<rest-api-host><rest-api-resource-uri>,如果是的话,该怎么办?
  • 我需要其他信息才能使它正常工作吗?

  • 谢谢!
    彼德

    最佳答案

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

    配置ADFS

    配置ADFS分为2部分。

    向ADFS注册客户端应用程序

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

    使用多种工具之一为客户端ID生成GUID。
    * CLIENT_ID和APP_NAME应该是唯一的。
    *对于Web客户端,重定向URI是身份验证服务在对用户进行身份验证之后将重定向您的调用的位置。它应该是一个端点,您可以在其中处理 token 并继续您的客户端应用程序。重定向URI并未真正与富客户端/服务/加载项一起使用。

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

    客户注册说明

    (也许可以在向导中进行,但这是我在网上找到的,对我们有用)
  • 以管理员身份登录到AD FS服务器,然后打开Windows PowerShell命令窗口。
  • 输入以下命令。在Windows PowerShell中
    Add-AdfsClient -ClientId <CLIENT_ID> -Name <APP_NAME> -RedirectUri <REDIRECT_URI>

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

    我发现this link很有用,它会带您完成向导的步骤以建立依赖方。

    依赖方注册说明

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

    您需要为此向导提供的值:
    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
    

    如果有机会,添加 claim 规则:
    SEND_LDAP_ATTRIBUTES_AS_CLAIMS = true
    ATTRIBUTE_STORE                = Active Directory
    SELECT_USEFUL_ATTRIBUTES       = User-Principal-Name; Email; Display-Name
    

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

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

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

    该库使编码非常简单,仅需几行。我遇到的问题是:
  • 我找不到对用于ADFS的URL的解释
    安全 token 服务(STS)
  • 我在这里找不到整个过程的文档(大多数文档集中在Azure FS上),我很难解决
    为客户和依赖方提供给ADFS的值是如何映射的
    到代码中使用的值。

  • 在代码中使用什么是ADFS终结点/URL?

    Microsoft的最佳做法是将您的ADFS/STS服务器URL命名为https://sts.domain.com(某些人使用https://adfs.domain.com,请询问您的服务器管理员)。但是,如果尝试从浏览器中执行此操作,则会得到404 - Not found并尝试在代码中检索 token ,因此ADAL库报告:
     The browser based authentication dialog failed to complete. Reason: The server has not found anything matching the requested URI (Uniform Resource Identifier).
    

    这就是我找到要使用的端点的方式:
  • ADFS在“https://sts.domain.com/federationmetadata/2007-06/federationmetadata.xml”上发布联盟元数据
  • 提取此文件并在文本编辑器中打开。
  • 在配置依赖方时,我们在指定资源端点时指定了“启用对WS-Federation Passive协议(protocol)的支持”,因此请在XML中搜索PassiveRequestorEndpoint
  • 使用此节点中的<Address>-在我的情况下为https://sts.domain.com/adfs/ls/。我不知道这将始终是该值,还是在设置ADFS时指定了该值,因此每个站点可能有所不同。

  • 代码中还要使用其他什么值?

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

    最简单的说,可以用3行代码+配置检索访问 token ,这将显示如何将我们在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;
    

    有用的引用
  • ASP.NET Core Token Authentication Guide
  • ADAL - Native App to REST service - Authentication with ACS via Browser Dialog
  • Create a line-of-business Azure app with AD FS authentication
  • OAuth 2 Simplified
  • 关于c# - 如何设置有效的本地ADFS URI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39961921/

    相关文章:

    azure - 为什么我的 Azure Web 应用服务在 Application Insights 中出现 HEAD 请求失败日志?

    c# - 此 OperationContextScope 被乱序处理

    .net - web.config 中以 ida 为前缀的 appSettings 键的用途

    c# - ADFS - Windows 集成 OR Forms 身份验证

    具有 ADFS SAML 身份验证的 Java Web 服务客户端

    c# - 跨 API 传递不可变集合的最佳模式是什么

    c# - 从 Request.Files 中删除文件

    c# - 引发登录/注册错误的异常是否合适?

    c# - 为什么 HttpContext.User.Identity.Name 在使用 ASP.NET Core 时对于等效于工作同步 Controller 的异步 Controller 显示为空?

    c# - 在图表上显示 X 和 Y 值的数据点