我正在使用Cordova构建我的第一个移动应用。后端服务存在于Azure上,因此我尝试使用Cordova的ADAL插件来进行身份验证。
首先,我发现该库不会像Angular的ADAL库那样进行拦截。我在我的Cordova应用程序中使用了Angular,并结合了外观的材料设计指令。拦截本来会很好,但据我所知,它目前还不存在(应该知道实施的难度)。
所以我现在写了一个服务,它将负责向Azure发送REST api请求,包括正确的身份验证令牌。它基于找到的样本here。
这就是我提出的:
var request = function(url)
{
createContext()
.then(function () {
getAuthToken().then(
function(token) {
sendRequest(token, url);
})
},
function (err) {
$log.error("Failed to create a context.");
});
};
首先,它将创建身份验证上下文:
function createContext () {
return $q(function (resolve, reject) {
var authenticationContext = Microsoft.ADAL.AuthenticationContext;
authenticationContext.createAsync(authority)
.then(function (context) {
authContext = context;
$log.log("Created authentication context for authority URL: " + context.authority);
resolve();
}, function (err) {
$log.error("Failed to create authentication context: " + pre(err))
reject();
});
});
};
使用上下文它应该获取身份验证令牌:
function getAuthToken()
{
if (authContext == null) {
$log.error('Authentication context isn\'t created yet. Create context first');
return;
}
return $q(function (resolve, reject) {
authContext.acquireTokenAsync(resourceUrl, appId, redirectUrl)
.then(function (authResult) {
resolve(authResult.accessToken);
}, function (err) {
$log.error("Failed to acquire token: " + pre(err));
reject();
});
});
}
然后它应该发送请求,但是我会把那部分留下来,因为它从来没有到达那里。我觉得有必要再次强调我在这个方面有一个完整的n00b,所以请对我很轻松,尤其是代码。可能还有很大的改进空间,我明白了。
当我实际运行它时,会弹出一个窗口,我需要使用我的Microsoft帐户登录,很酷。我第一次尝试这个时甚至有两个因素身份验证,非常好!所以我登录后回到代码中。但现在 authresult 变量的状态为"失败"并且结果中没有访问令牌。不幸的是,也没有迹象表明出了什么问题。所以问题的第一部分是;这里可能出了什么问题?
现在我们来看问题的第二部分;你如何正确调试这些东西?在我的桌面上,我会运行Fiddler查看通信,但我不知道如何为Android做到这一点。我在我的设备上调试btw,因为某些原因我可用的所有模拟器都非常慢(VS和谷歌),即使我的硬件规格应该支持它们就好了。
感谢您的任何指示!
更新03-02-2016
稍微调整代码,我决定在登录功能中打包,这样可以缩短样本:
var createContext = function () {
if (authContext == null) {
authContext = new Microsoft.ADAL.AuthenticationContext(authority);
}
};
var getAuthToken = function () {
if (authContext == null) {
$log.error('Authentication context isn\'t created yet. Create context first');
return;
}
return $q(function (resolve, reject) {
authContext.acquireTokenAsync(endpointUrl, appId, redirectUrl)
.then(function (authResult) {
resolve(authResult.accessToken);
}, function (err) {
$log.error("Failed to acquire token: " + pre(err));
reject();
});
});
}
var login = function () {
createContext();
getAuthToken();
}
此代码在以下输入变量上运行:
var authority = 'https://login.windows.net/[tenantid]';
var resourceUrl = 'https://graph.windows.net/';
var appId = '1ef41b17-0943-4359-bc12-014f4fd2d841';
var redirectUrl = 'http://MyApp';
我现在使用chrome:// inspect来查看线路上的内容。令我惊讶的是,我看到Azure返回了一个有效的SAML令牌。它已经有了我的名字以及我认可的所有内容,我们将在验证失败后发送它们。所以看起来即使响应没问题,ADAL库也没有给我一个正确的响应(Status = Failed)。再也没有关于如何进行的线索:S
答案 0 :(得分:5)
我刚解决了。就像人们所期望的那样,补救措施就像他们得到的一样简单。在Azure AD中配置应用程序,我选择了" Web应用程序"类型应用程序,因为这是一个使用Angular和所有的Web应用程序。现在我想因为Cordova将事物翻译成本机代码,所以这不是正确的选择。一旦我创建了一个新的应用程序作为"本机应用程序"相反,并使用了那个客户端ID,一切都开始工作....真诚地希望这将有助于未来的其他人......!
答案 1 :(得分:0)
我有一个非常类似的问题,我试图从Cordova应用程序访问web api。当我调用acquireTokenAsync时,我正在使用App ID Uri作为resouceURL访问的web api。当我将其更改为Web Api的客户端ID时,它确实有效。