【问题标题】:Securing a Web API with Windows Server 2012 R2 ADFS 3.0 and Katana使用 Windows Server 2012 R2 ADFS 3.0 和 Katana 保护 Web API
【发布时间】:2014-07-12 16:08:14
【问题描述】:

我想制作一个与 Web API 应用程序对话并使用 ADFS 3.0(在 Windows 2012 R2 上)进行身份验证的 MVC Web 应用程序。

我设法让 MVC Web 应用程序使用 ADFS 进行身份验证。 并按照 Vittorio Bertocci 的这篇文章中所示配置所有内容

http://www.cloudidentity.com/blog/2013/10/25/securing-a-web-api-with-adfs-on-ws2012-r2-got-even-easier/

现在我使用来自 nuget 的 AAL 的最新预发布版本

现在通过 Web MVC 应用程序使用 ADFS 进行身份验证后,我尝试调用 webapi

public async Task<String> CallSecuredAPI()
        {
            string authority = "https://fs.domain.com/adfs";
            string resourceURI = "https://{hostheader}/SecuredAPI";
            string clientID = "ExternalWebSite1";
            string clientReturnURI = "https://{hostheader}/ExternalSite";

            AuthenticationContext ac = new AuthenticationContext(authority, false);
            AuthenticationResult ar = ac.AcquireToken(resourceURI, clientID, new   Uri(clientReturnURI));

            string authHeader = ar.CreateAuthorizationHeader();
            var client = new HttpClient();
            HttpRequestMessage request =
                new HttpRequestMessage(HttpMethod.Get, "https://hostheader/SecuredAPI/api/Claims");
            request.Headers.TryAddWithoutValidation("Authorization", authHeader);
            HttpResponseMessage response = await client.SendAsync(request);
            string responseString = await response.Content.ReadAsStringAsync();
            return responseString;
        }

但我收到此错误,我认为客户端不是基于 UI 的客户端或 WPF,windows App。有人可以让我知道我是否做错了什么。

![尝试使用 AAL 获取授权码时出错][1]

“/ExternalSite”应用程序中的服务器错误。

当应用程序未在 UserInteractive 模式下运行时显示模式对话框或表单不是有效操作。指定 ServiceNotification 或 DefaultDesktopOnly 样式以显示来自服务应用程序的通知。

说明:在执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详细信息:System.InvalidOperationException:当应用程序未在 UserInteractive 模式下运行时显示模式对话框或表单不是有效操作。指定 ServiceNotification 或 DefaultDesktopOnly 样式以显示来自服务应用程序的通知。

Source Error: 


Line 43: 
Line 44:             AuthenticationContext ac = new AuthenticationContext(authority, false);
Line 45:             AuthenticationResult ar = ac.AcquireToken(resourceURI, clientID, new Uri(clientReturnURI));
Line 46:             
Line 47:             string authHeader = ar.CreateAuthorizationHeader();

Source File: c:\Users\balakrishna.takkalla\Documents\Visual Studio 2013\Projects\ExternalSite\ExternalSite\Controllers\HomeController.cs    Line: 45 

Stack Trace: 


[InvalidOperationException: Showing a modal dialog box or form when the application is not running in UserInteractive mode is not a valid operation. Specify the ServiceNotification or DefaultDesktopOnly style to display a notification from a service application.]
   System.Windows.Forms.Form.ShowDialog(IWin32Window owner) +5701502
   Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.WindowsFormsWebAuthenticationDialog.ShowBrowser() +18
   Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.WindowsFormsWebAuthenticationDialog.OnAuthenticate() +23
   Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.WindowsFormsWebAuthenticationDialogBase.AuthenticateAAD(Uri requestUri, Uri callbackUri) +284
   Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.InteractiveWebUI.OnAuthenticate() +103
   Microsoft.IdentityModel.Clients.ActiveDirectory.OAuth2Request.SendAuthorizeRequest(Authenticator authenticator, String resource, Uri redirectUri, String clientId, String userId, PromptBehavior promptBehavior, String extraQueryParameters, IWebUI webUi, CallState callState) +363
   Microsoft.IdentityModel.Clients.ActiveDirectory.<>c__DisplayClass9b.<AcquireAuthorization>b__9a() +111
   System.Threading.Tasks.Task.Execute() +110

【问题讨论】:

  • 您是否阅读了错误信息?它不仅告诉你出了什么问题,它还告诉你如何解决它。 “当应用程序未在 UserInteractive 模式下运行时显示模式对话框或表单不是有效操作。指定 ServiceNotification 或 DefaultDesktopOnly 样式以显示来自服务应用程序的通知。”
  • 感谢 Robert Harvey 是的,我确实读过它,但不确定我是否应该继续进行更改,因为我不希望在此操作期间出现任何弹出窗口。请让我知道它是否有效您知道的错误消息。
  • 您的堆栈跟踪清楚地表明某些代码正在尝试打开模式对话框。我会尝试设置错误消息中描述的一种样式,以便您可以看到模态对话框试图向您显示的内容。 ServiceNotification 完全有可能给你一个日志条目而不是一个对话框,尽管我对那里正在进行的 ActiveDirectory 操作并不是很熟悉。
  • 是的,试图从 Microsoft 的 AAL 库中打开 Windows 消息框的代码,我无权更改此处提到的内容,因为这需要作为 MessageBox 代码的重载应用. stackoverflow.com/questions/8928713/…
  • 我确实知道我做错了什么,我认为 AcquireToken 不是正确的方法,但应该使用 AquireTokenSilent 扩展,因为我不希望用户输入详细信息。因为来自 cloudidentity 的示例是针对 WPF 的,并且可以在该场景中得到提示。

标签: asp.net-mvc asp.net-web-api adfs2.1


【解决方案1】:

如果我理解正确:您想从 MVC 应用程序的代码隐藏中访问 Web API。 今天,Azure Active Directory 可以实现这种拓扑,您可以在示例https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet 中看到它的实际效果(我正在将其更新到最新的 ADAL 刷新,您可以查看 RCUpdate 分支以查看工作进行中)。

但是,今天从 ADFS WS2012 R2 无法实现该拓扑。原因是 MVC 应用程序(和任何其他网站)是机密客户端,OAuth2 处理它的方式与公共客户端不同(您用作起点的 WPF 应用程序是公共客户端)。在您的目标场景中,要使用 ADAL 从机密客户端获取令牌,您将使用 ADAL 的方法 AcquireTokenByAuthorizationCode(请参阅我提到的示例)。但是 ADFS WS2012 R2 无法处理该方法。今天,ADFS WS2012 R2 中的 OAuth2 支持仅限于公共客户端。

抱歉带来了坏消息!作为一种缓解措施,您可能会考虑将您的 ADFS 与 AAD 租户联合:此时您将能够做您想做的事情,以 ADFS 用户身份进行身份验证,但从 AAD 获取令牌(它确实支持必要的 OAuth2 授权)。 高温高压 五、

【讨论】:

  • 感谢 vibronet,我很高兴阅读您的回复,因为我正在努力想办法摆脱处理 ADFS 样本...顺便说一下,我关注您在 CloudIdentity 上的所有帖子,它们是非常好...我喜欢您将我的 ADFS 与可以解决我的问题的 AAD 租户联合的想法...是的,我已经看过您的所有帖子...使用 AAD 我对样本感到满意...谢谢为博客...再次
  • 我对如何“将您的 ADFS 与 AAD 租户联合”有一个小小的疑问,任何链接或建议都会很好......我的想法是你的意思是 1 )在 AAD 中创建新域时使用“使用现有域”选项将两者(ADFS 和 AAD)指向同一个 AD 林,或者 2)在 AAD 中是否有任何方法,如 ACS(联合代理)我可以使用 AAD 将其指向 ADFS。
  • 嗨巴拉,谢谢你的好话! ADFS-AAD集成,可以从msdn.microsoft.com/en-US/library/azure/dn441213.aspx开始
  • 感谢 Vibronet 的帮助。
  • 您好 Vittorio,关于何时(或是否)这种使用 ADAL 从 ADFS WS2012 R2 获取令牌的场景可能会实施的任何建议?
猜你喜欢
  • 2014-08-05
  • 1970-01-01
  • 2016-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多