【问题标题】:Consume Secure Azure API from SharePoint online从 SharePoint 在线使用 Secure Azure API
【发布时间】:2016-12-13 13:05:02
【问题描述】:
我开发了具有身份验证功能的 Azure API 应用程序,使用 Azure Active Directory 登录,我需要从 SharePoint 在线使用此 API,我
我需要验证和使用 azure API,没有登录提示,每件事都应该在脚本中处理
需要使用 ADAL.js 来验证安全 API ,我找不到任何关于 JavaScript 代码的好的参考资料,我想知道是否有人有好的参考资料应该是什么样的 JavaScript 代码?
谢谢!
【问题讨论】:
标签:
azure
authentication
sharepoint-online
azure-api-apps
adal.js
【解决方案1】:
以下是使用 JavaScript 和 ADAL.js 库从 SharePoint Online 调用 Azure 托管 API 的步骤,没有签名提示,所有内容都应在脚本中使用 ADAL.js 处理以验证安全 API
创建和配置 API
- 创建 Azure API
- 在 azure 中发布你的 azure API
-
浏览到 azure 门户,选择您的 API 应用程序,选择 Authentication/Authorizations
现在 API 受 Azure AD 保护,如果您通过浏览器导航 API,系统将提示您登录
- 当我们在 Express 模式下设置身份验证时,会在 Azure Active Directory 中自动创建应用程序,您可以在 Azure AD 应用程序下看到名称
- 导航到Azure管理门户,点击左侧导航中的活动目录,
- 单击将与您的 Office 365 联合的目录(或您想要调用 azure API 的任何源,它使用与您为 API 身份验证配置的相同的 Azure Active Directory)
- 单击应用程序,您会在列表中找到您的 AD 应用程序,该应用程序是使用 Express 方法创建的,正如我们在步骤 nr.3 中讨论的那样
- 现在我们需要在 AAD 中创建新的应用程序,这将是我们从 office 365 到 Azure API 的通信渠道,单击页脚上的添加
- 输入名称并选择“WEB APPLICATION AND/OR WEB AP”选项
- 对于 登录 URL,输入您计划从其调用 Azure API 的 SharePoint 在线 URL
- 对于 APP ID URL,输入唯一的 Url,这将用作您应用的唯一逻辑标识符。
- 应用创建完成后,点击配置,复制Client ID,后面会用到
- 在对其他应用程序的权限下,单击“添加应用程序”,在下一页选择“所有应用程序s”并选择您 Azure您在步骤 nr.8 中仔细检查并确认的 API 应用程序
- 您将被重定向回配置页面,在对其他应用程序的权限下,现在您看到您的 azure API 应用程序已在此处列出,单击 委派权限,选择访问应用程序
- 在页面底部,点击管理清单 > 下载清单t。
- 将文件下载到可以编辑的位置。
- 在下载的清单文件中,搜索 oauth2AllowImplicitFlow 属性。将此属性的值从 false 更改为 true,然后保存文件。
- 点击管理清单 > 上传清单,然后上传您在上一步中更新的文件。
- Azure 管理门户,选择设置并复制相关 AAD 的 AAD 订阅 ID
从 SharePoint Online 调用 Azure API
完成上述步骤后,您可以从使用上述相同 Active 目录的 sharePoint online 调用 azure API
- 编辑页面并添加脚本编辑器 Web 部件
- 添加以下脚本
· subscriptionId,见步骤 nr.20
· clientId 见步骤 nr.13
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.13/js/adal.min.js"></script>
<script type="text/javascript">
function CallAzureAPI() {
"use strict";
var subscriptionId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var clientId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
window.config = {
subscriptionId: subscriptionId,
clientId: clientId,
postLogoutRedirectUri: window.location.origin,
endpoints: {
AzureApiUri: 'https://xxxxxxxxxxxx.azurewebsites.net'
},
cacheLocation: 'localStorage'
};
var authContext = new AuthenticationContext(config);
var isCallback = authContext.isCallback(window.location.hash);
authContext.handleWindowCallback();
if (isCallback && !authContext.getLoginError()) {
window.location = authContext._getItem(authContext.CONSTANTS.STORAGE.LOGIN_REQUEST);
}
// If not logged in force login
var user = authContext.getCachedUser();
if (user) {
// Logged in already
console.log(user);
}
else {
authContext.login();
}
// Acquire token for Files resource.
authContext.acquireToken(config.endpoints. AzureApiUri, function (error, token) {
// Handle ADAL Errors.
if (error || !token) {
console.log('ADAL error occurred: ' + error);
return;
}
var ApiUri = "https://xxxxxxxxx.azurewebsites.net/api/Get";
$.ajax({
type: "GET",
url: ApiUri,
headers: {
'Authorization': 'Bearer ' + token,
}
}).done(function (response) {
console.log('Successfully called API.');
console.log(response);
}).fail(function () {
console.log('Calling API failed.');
});
});
}
</script>
<input type='button' value='Call Azure API' onclick=" CallAzureAPI ();"/>
这个解决方案虽然在一段时间后有效(后来我发现 AAD cookie 过期了)我们得到这个错误“令牌更新操作因超时而失败”,
我做了一些研究,发现他的 getCachedUser 或 getUser 方法在浏览器存储中查找 id_token 并在缓存中有令牌时返回非空用户。但它不会考虑令牌到期时间。
这里发生的事情是由于使用了 localStorage,当重新打开浏览器时,令牌会保留在缓存中(因此 getCachedUser 返回一个非空对象),但 AAD cookie 已过期(除非用户选中了让我登录复选框)在登录)。由于 cookie 已过期,获取令牌调用失败并出现“需要登录”错误。
所以作为我检查的解决方法,让我保持登录在登录时复选框并且它有效。
【解决方案2】:
可以使用 JavaScript 从 SharePoint 在线调用受 Azure AD 保护的 Web API,但是非常复杂。
以下是供您参考的步骤:
- 开发受 Azure AD 保护的 Web API
- 在同一租户上注册本机应用程序
- 为原生应用启用隐式流
- 授权本机应用从 Azure 门户访问 Web API
- 使用admin_consent 为本机应用程序授予组织权限
- 在 Web API 项目中为 OAuth 2.0 请求的重定向页面开发网页
-
在网页中编写代码,使用 windows.postMessage 将令牌发布到父页面
$().ready(function () {
if (window.parent != null) {
// get the token from URL here
var token = "123";
console.log(window.location);
window.parent.postMessage(token, "*");
}
})
在 SharePoint 在线页面中,使用 iframe 发送隐含流,如下代码
<iframe id="iframe_id" src="https://login.microsoftonline.com/{tenanit}.onmicrosoft.com/oauth2/authorize?response_type=token&client_id={clientId}&resource={webApiAppIdUri}&redirect_uri={redirect_uri}&prompt=none"></iframe>
<script>
var token = "";
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event) {
token=event.data;
console.log(event.data);
}
</script>
下图有助于理解进度: