Cordova应用程序中使用JWT OAuth 2.0令牌的Azure MFA

时间:2017-03-22 14:12:21

标签: cordova azure oauth multi-factor

我正在开发一个Cordova应用程序(迄今为止)使用密码授权从Azure中的Microsoft标准OAuth提供程序中检索JWT:

https://login.microsoftonline.com/[tenant]/oauth2/token

工作正常。但是,我们正在向外部交易者开放我们的申请,业主希望增加MFA。

因此,我在Azure中创建了一个MFA提供程序,我已为MFA启用了一个测试帐户。

我目前正在使用InAppBrowser插件打开重定向请求 - 这似乎有效 - 它打开登录页面,文本,我把代码放入,然后它完成登录到“应用程序”初始屏幕(默认Azure登录用户)。

我的问题是确定登录成功,并检索JWT。由于MFA,登录服务器现在在初始登录时返回以下“MFA”错误(实际上不是错误):

interaction_required

但是,一旦MFA完成,我不知道去哪里获取我的令牌/刷新令牌。如果我重新提交登录,它只会发回“interaction_required”消息,即使在MFA过程中选择了“不再询问[X]天”。

我希望这个问题很清楚。如果没有,请告诉我,我会在必要时进行修改。

我目前没有使用ADAL或任何cordova插件进行身份验证。我自己打了终点。答案可能是我必须使用ADAL。

1 个答案:

答案 0 :(得分:1)

好的伙计们,这是问题所在。由于我使用的是密码授予,因此我没有访问/ oauth2 / authorize端点 - 密码授权不需要 - 您可以直接访问/ oauth2 / token ...

使用MFA时,/ oauth2 / authorize是必需的。如果启用了MFA,它会重定向并为您处理一切(非常简单)。您只需等待重定向网址,auth代码是一个查询参数,因此非常容易推断。

浏览器重定向后,您获取授权代码,然后将其提交到/ oauth2 /令牌服务器,不带用户名/密码(也不需要授权标头,这很好,因为你不喜欢不得不两次要求它 - 一次用于MFA,一次用于传递给/令牌 - 好的打电话给微软)。

流量

testMFA = function () {
var url = "https://login.microsoftonline.com/[tenantID]/oauth2/authorize?client_id=[clientID]&response_type=code&response_mode=query";;
var target = "_blank";
var options = "location=yes";
inAppBrowserRef = cordova.InAppBrowser.open(url, target, options);
with (inAppBrowserRef) {
    try {
        addEventListener('loadstart', loadStartCallBack);
        addEventListener('loadstop', loadStartCallBack);
        addEventListener('loaderror', loadStartCallBack);
        addEventListener('exit', loadStartCallBack);
    }
    catch (ex) {
        alert(ex);
    }
}

}

然后,在'loadStartCallBack'中:

else if (event.url.split('/')[2] == '[returnURLWithoutHttps://]') {
        var fullstring = event.url.split('/')[3].split('?code=')[1] 
        var code = fullstring.split('&')[0];
        var sess_state = fullstring.split('session_state=')[1];
        localStorage.tokenCode = code;
        sessionStorage.sess_state = sess_state;
        inAppBrowserRef.close();
        getToken();
    }

然后,您将授权代码传递到/ oauth2 /令牌服务器,并接收您的令牌(我将留下密码授予的评论,以供将来以密码授予开始的读者):

var data =
'resource=[resourceURL]' +
//'&username=' + window.sessionStorage.loginUser + 
//'&password=' + password +
'&client_id=' + clientId +
'&code=' + authCode +
'&grant_type=authorization_code' + 
//'&grant_type=password';
'&response_type=token';
var dataFinal = encodeURI(data);

就是这样。希望有一天能帮到某人。