ADAL JS在调用WebApi时不附加用户令牌

时间:2016-03-15 10:21:09

标签: javascript azure asp.net-web-api adal.js

我正在使用ADAL JS来针对Azure AD对用户进行身份验证。因为我是ADAL JS的新手,所以我开始阅读以下文章,我发现这些文章内容非常丰富:

阅读文章后,我的印象是ADAL JS拦截了服务调用,如果服务URL被注册为AuthenticationContext配置中的一个端点,它会将JWT令牌附加为身份验证承载信息。

然而,我发现在我的情况下并没有发生同样的情况。经过一些挖掘,在我看来,只有当adal-angular计数器部分也被使用时才有可能,我目前没有使用它,只是因为我的Web应用程序不是基于Angular。

如果我的理解是正确的,请告诉我。如果我需要明确地添加承载信息,可以做同样的事情,但我更担心的是我是否缺少一些开箱即用的设施。

其他详细信息:我目前的配置如下所示:

private endpoints: any = {
    "https://myhost/api": "here_goes_client_id"
}
...
private config: any;
private authContext: any = undefined;
....
this.config = {
    tenant: "my_tenant.onmicrosoft.com",
    clientId: "client_id_of_app_in_tenant_ad",
    postLogoutRedirectUri: window.location.origin,
    cacheLocation: "sessionStorage",
    endpoints: this.endpoints
};
this.authContext = new (window["AuthenticationContext"])(this.config);

同样在服务器端(WebApi),身份验证配置(Startup.Auth)如下:

public void ConfigureOAuth(IAppBuilder app, HttpConfiguration httpConfig)
{
    app.UseWindowsAzureActiveDirectoryBearerAuthentication(
        new WindowsAzureActiveDirectoryBearerAuthenticationOptions
        {
            Tenant = "my_tenant.onmicrosoft.com",
            TokenValidationParameters = new TokenValidationParameters
            {
                ValidAudience = "client_id_of_app_in_tenant_ad"
            }
         });
}

但是,Authorization中的request.Headers始终为空。

更新:似乎同样适用于令牌的自动续订;当与adal-angular结合使用时,令牌的更新可以通过调用引擎盖下的AuthenticationContext.acquireToken(resource, callback)无缝地工作。如果我错了,请纠正我。

2 个答案:

答案 0 :(得分:2)

  

在阅读文章后,我的印象是ADAL JS拦截了服务调用,如果服务URL被注册为AuthenticationContext配置中的一个端点,它会将JWT令牌作为Authentication Bearer信息附加。

仅当您的应用程序基于角度时才会起作用。正如你所提到的,它的逻辑生活在adal-angular。

但是,如果您想坚持使用纯JS,那么您将无法获得自动" get-access-token-and-attach-it-to-header"支持。您可以使用acquireToken(resource, callback api获取端点的令牌。但是你必须在将请求发送到api的控制器中做一些工作。

这可能会让你有所了解:https://github.com/Azure-Samples/active-directory-javascript-singlepageapp-dotnet-webapi/blob/master/TodoSPA/App/Scripts/Ctrls/todoListCtrl.js。此示例不使用角度。

答案 1 :(得分:0)

ADAL.JS与v2.0隐式流程不兼容。自从我最近设置项目并且不认为项目是向后兼容的,我无法使它工作。

这非常令人困惑,我花了很长时间才弄清楚我是在混淆版本,并且不能将ADAL.JS与v2.0一起使用。一旦我删除它,事情变得更顺畅,只是做了几个XHR请求和一个弹出窗口,实际上没有魔法!

以下是v2的代码:

function testNoADAL() {
    var clientId = "..guid..";
    var redirectUrl = "..your one.."
    var authServer = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?";
    var responseType = "token";
    var stateParam = Math.random() * new Date().getTime();

    var authUrl = authServer +
                                "response_type=" + encodeURI(responseType) +
                                "&client_id=" + encodeURI(clientId) +
                                "&scope=" + encodeURI("https://outlook.office.com/Mail.ReadWrite") +
                                "&redirect_uri=" + encodeURI(redirectUrl) +
                                "&state=" + stateParam;

    var popupWindow = window.open(authUrl, "Login", 'width=' + 300 + ', height=' + 600 + ', top=' + 10 + ', left=' + 10 + ',location=no,toolbar=yes');
    if (popupWindow.focus) {
        popupWindow.focus();
    }
}

注意:redirectUrl会出现在弹出窗口中,需要在其中包含代码来传递位置哈希,例如:

<script>window.opener.processMicrosoftAuthResultUrl(location.hash);window.close();</script>

function processMicrosoftAuthResultUrl(hash) {
    if (hash.indexOf("#") == 0) {
        hash = hash.substr(1);
    }
    var obj = getUrlParameters(hash);
    if (obj.error) {
        if (obj.error == "invalid_resource") {
            errorDialog("Your Office 365 needs to be configured to enable access to Outlook Mail.");
        } else {
            errorDialog("ADAL: " + obj.error_description);
        }
    } else {
        if (obj.access_token) {
            console.log("ADAL got access token!");
            var token = obj.access_token;
            var url = "https://outlook.office.com/api/v2.0/me/MailFolders/Inbox/messages";
            $.ajax({
                type: "GET",
                url: url,
                headers: {
                    'Authorization': 'Bearer ' + token,
                },
            }).done(function (data) {
                console.log("got data!", data);
                var message = "Your latest email is: " + data.value[0].Subject + " from " + data.value[0].From.EmailAddress.Name+ " on " + df_FmtDateTime(new Date(data.value[0].ReceivedDateTime));
                alertDialog(message);

            }).fail(function () {
                console.error('Error getting todo list data')
            });
        }
    }
}

function getUrlParameters(url) {
    // get querystring and turn it into an object
    if (!url) return {};
    if (url.indexOf("?") > -1) {
        url = url.split("?")[1];
    }
    if (url.indexOf("#") > -1) {
        url = url.split("#")[0];
    }
    if (!url) return {};
    url = url.split('&')
    var b = {};
    for (var i = 0; i < url.length; ++i) {
        var p = url[i].split('=', 2);
        if (p.length == 1) {
            b[p[0]] = "";
        } else {
            b[decodeURIComponent(p[0])] = decodeURIComponent(p[1].replace(/\+/g, " "));
        }
    }
    return b;
}