2

我有一个运行 ASP.Net Web API 应用程序的 Azure Worker 角色。这受 ACS 保护。当我使用浏览器浏览 Web api 时,ACS 要求我针对 Google 或 LiveId 进行身份验证。当我进行身份验证时,我可以看到数据。

我正在尝试从 Win 8 Metro Style App 访问相同的 API。我正在尝试使用 WebAuthenticationBroker。

WebAuthenticationResult webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(
                                                        WebAuthenticationOptions.None,
                                                        new Uri("https://xxxxx.accesscontrol.windows.net:443/v2/wsfederation?wa=wsignin1.0&wtrealm=http%3a%2f%2fyyyyy.cloudapp.net%2f"),
                                                        new Uri("http://yyyyy.cloudapp.net/")
                                                       );

当我启动应用程序时,它要求我像以前一样通过 Google 或 LiveId 进行身份验证。这通过了,我得到了一个成功的结果。

然后我使用 HttpClient 创建对 API 的调用:

    HttpClient client = new HttpClient();
    Uri _baseUri = new Uri("http://yyyyy.cloudapp.net/api/");
    client.BaseAddress = _baseUri;

    var response = client.GetAsync("Values/").Result;
    var responseBodyAsText = response.Content.ReadAsStringAsync().Result;

    var ids = JsonConvert.DeserializeObject<IList<int>>(responseBodyAsText);

这种工作,它似乎正确导航到 URI,但返回的有效负载是 HTML 要求我登录,而不是我期望的 JSON 数据。

我在这方面花费的时间比明智的要多,而且我的想法已经用完了!有人可以帮忙吗?

4

3 回答 3

2

在 localhost 上进行测试时,您必须确保 ACS 可以访问您的计算机。

正如@caleb 所写,您需要侦听令牌并将其重定向给代理。您可以查看我的帖子,其中包含一个工作示例以及如何设置它。

WebAuthenticationBroker 是否在 Windows 8 Metro App post Release Candidate 中工作

于 2012-09-27T08:24:46.437 回答
1

WebAuthenticationBroker继续浏览,直到浏览器要加载的 URL 是 callbackUri 参数中指定的 URL。然后它将向您返回最终 url,包括任何查询参数。它实际上从未向 callbackUri 发出请求。

您遇到的问题是 ACS 实现的 WS-Federation 协议将令牌发回返回 url(在 ACS 配置门户中指定),这可能与您在 AuthenticateAsync 方法中指定为 callbackUri 参数的 url 相同。

您需要做的是处理该帖子并将请求重定向到 callbackUri,但使用包含令牌的查询字符串。

我正在使用 WebApi 和 WIF,并且我将 callbackUri 指定为http://localhost:3949/api/federationcallback/end并将返回 url 指定为http://localhost:3949/api/federationcallback. 这使我可以让控制器处理帖子,然后使用 URL 中的令牌进行重定向。控制器看起来像这样。

public class FederationcallbackController : ApiController
{
    public HttpResponseMessage Post()
    {
        var response = this.Request.CreateResponse(HttpStatusCode.Redirect);
        response.Headers.Add("Location", "/api/federationcallback/end?acsToken=" + ExtractBootstrapToken());

        return response;
    }

    protected virtual string ExtractBootstrapToken()
    {
        return HttpContext.Current.User.BootstrapToken();
    }
}

然后我可以像这样得到令牌:

var authenticateResult = await WebAuthenticationBroker.AuthenticateAsync(
            WebAuthenticationOptions.None,
            new Uri("https://xyz.accesscontrol.windows.net:443/v2/wsfederation?wa=wsignin1.0&wtrealm=http%3a%2f%2flocalhost:3949%2f"),
            new Uri("http://localhost:3949/api/federationcallback/end"));

var oauthToken = authenticateResult.ResponseData.Substring(authenticateResult.ResponseData.IndexOf("acsToken=", StringComparison.Ordinal) + 9);
于 2012-09-27T02:48:57.337 回答
0

WebAuthenticationResult调用 API 时不应该重新使用令牌吗?

var webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.None, 
        new Uri("https://xxxxx.accesscontrol.windows.net:443/v2/wsfederation?wa=wsignin1.0&wtrealm=http%3a%2f%2fyyyyy.cloudapp.net%2f"), new Uri("http://yyyyy.cloudapp.net/"));

var client = new HttpClient();
client.DefaultRequestHeaders.Authorization
        = new AuthenticationHeaderValue("OAuth", webAuthenticationResult.ResponseData);
于 2012-08-01T12:07:52.043 回答