设想:
我有两个ASP.NET Web应用程序分别托管在Windows Azure上,并且都与同一个Azure Active Directory租户关联:
一个具有AngularJS SPA前端和adal.js库的MVC应用程序,用于在客户端上处理Azure AD身份验证。
带有Microsoft OWIN中间件的Web API,用于在服务器上处理Azure AD身份验证。
问题:
当角度引导程序启动客户端应用程序时,在通过oauth重定向到适当的身份验证机构后,页面将正确加载,而adal.js库正确地为每个应用程序检索和存储了不同的令牌(通过检查中的Resources / Session-Storage选项卡进行验证) Chrome开发者工具)。但是,当客户端应用尝试访问或更新API中的任何数据时,CORS预检请求将以302重定向响应到身份颁发机构,这会在控制台中导致以下错误:
XMLHttpRequest无法加载https://webapi.azurewebsites.net/api/items。该请求已重定向到“ https://login.windows.net/ {authority-guid} / oauth2 / authorize?response_type = id_token&redirect_uri = .... etc..etc ..”,该请求不适用于跨域请求需要进行飞行前检查。
标头示例(匿名):
要求 选项/ api / items HTTP / 1.1 主机:webapi.azurewebsites.net 连接:保持活动状态 访问控制请求方法:GET 访问控制请求标头:接受,授权 来源:https://mvcapp.azurewebsites.net 用户代理:Mozilla / 5.0(Windows NT 6.3; WOW64)AppleWebKit / 537.36(KHTML,如Gecko)Chrome / 39.0.2171.99 Safari / 537.36 接受: */* 引荐来源:https://mvcapp.azurewebsites.net/ 回复 找到HTTP / 1.1 302 内容长度:504 位置:https://login.windows.net/ {authority-guid} /oauth2/authorize?response_type=id_token&redirect_uri=https%3A%2F%2F....etc..etc.%2F&client_id= {api-guid} &scope = openid + profile + email&response_mode = form_post&state = ... etc ... 服务器:Microsoft-IIS / 8.0 X-Powered-by:ASP.NET Set-Cookie:ARRAffinity = 4f51 ... snip .... redact .... db6d; Path = /; Domain = webapi.azurewebsites.net
我做过/尝试过的
问题
有什么方法可以使与Azure AD租户关联的Web API不能在CORS预检请求上重定向?我是否在adal.js库和/或OWIN启动代码中缺少某些初始化设置(请参见下文)?Azure门户中是否存在允许OPTIONS请求到达OWIN管道的设置?
相关代码:
adal.js初始化
angular.module("myApp", ["ngRoute", "AdalAngular"])
.config(["$routeProvider", "$locationProvider", "$httpProvider", "adalAuthenticationServiceProvider",
function ($routeProvider, $locationProvider, $httpProvider, adalProvider) {
$routeProvider.when("/", { // other routes omitted for brevity
templateUrl: "/content/views/home.html",
requireADLogin: true // restrict to validated users in the Azure AD tenant
});
// CORS support (I've tried with and without this line)
$httpProvider.defaults.withCredentials = true;
adalProvider.init({
tenant: "contoso.onmicrosoft.com",
clientId: "11111111-aaaa-2222-bbbb-3333cccc4444", // Azure id of the web app
endpoints: {
// URL and Azure id of the web api
"https://webapi.azurewebsites.net/": "99999999-zzzz-8888-yyyy-7777xxxx6666"
}
}, $httpProvider);
}
]);
OWIN中间件初始化
public void ConfigureAuth(IAppBuilder app)
{
// I've tried with and without the below line and also by passing
// in a more restrictive and explicit custom CorsOptions object
app.UseCors(CorsOptions.AllowAll);
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
TokenValidationParameters = new TokenValidationParameters
{
// Azure id of the Web API, also tried the client app id
ValidAudience = "99999999-zzzz-8888-yyyy-7777xxxx6666"
},
Tenant = "contoso.onmicrosoft.com"
}
);
// I've tried with and without this
app.UseWebApi(GlobalConfiguration.Configuration);
}
WebApiConfig初始化
public static void Register(HttpConfiguration config)
{
// I've tried with and without this and also using both this
// and the OWIN CORS setup above. Decorating the ApiControllers
// or specific Action methods with a similar EnableCors attribute
// also doesn't work.
var cors = new EnableCorsAttribute("https://mvcapp.azurewebsites.net", "*", "*")
{
cors.SupportsCredentials = true // tried with and without
};
config.EnableCors(cors);
// Route registration and other initialization code removed
}
API OPTIONS动词处理程序注册
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="OPTIONSHandler" path="*" verb="OPTIONS" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
相关资源
一次或一次,我已经尝试了以下(以及更多)论坛和博客文章以及github示例代码中几乎所有可以想象的组合。
解决(某种)
这似乎是由部署问题引起的,尤其是最初将应用程序发布到Azure的方式。这两个应用程序最初都是使用Windows身份验证编写的,并已部署到标准(即非Azure)Web服务器上。使用这些技术,这些应用程序可以按预期工作。
根据新的业务需求,我一直在努力将其迁移到Azure。我遵循的过程是:
有时,我注意到VS Publish向导的“设置”选项卡上的“启用组织身份验证”选项,并开始使用它来将应用程序与租户关联。因为我已经手动关联了它们,所以Visual Studio最终为每个应用程序创建了另一个Azure AD应用程序,结果是两个。
最后,这是做什么的:
现在,选项预检请求不再是302重定向。
相反,它们现在是405 Method Not Allowed,与该线程非常相似。进步,某种程度上。
即使它仍然不能端到端地工作,我也将保留此答案(而不是删除问题),以防它可能帮助其他经历Azure 302重定向的CORS预检的人。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句