gpt4 book ai didi

angularjs - CORS 预检请求在 Azure 托管 Web API 中通过 302 重定向进行响应

转载 作者:行者123 更新时间:2023-12-04 08:07:15 28 4
gpt4 key购买 nike

场景:

我有两个分别托管在 Windows Azure 上的 ASP.NET Web 应用程序,并且都与同一个 Azure Active Directory 租户关联:

  1. 具有 AngularJS SPA 前端和 adal.js 的 MVC 应用程序用于在客户端处理 Azure AD 身份验证的库。

  2. 带有 Microsoft OWIN 中间件的 Web API,用于处理服务器上的 Azure AD 身份验证。

问题:

当 Angular 引导客户端应用程序时,页面在经过 oauth 重定向到正确的身份验证机构后正确加载,并且 adal.js 库正确检索并存储每个应用程序的不同 token (通过检查资源进行验证) Chrome 开发工具中的/Session-Storage 选项卡)。 但是,当客户端应用程序尝试访问或更新 API 中的任何数据时,CORS 预检请求将通过 302 重定向到身份验证机构进行响应,这会导致以下错误在控制台中:

XMLHttpRequest cannot load https://webapi.azurewebsites.net/api/items. The request was redirected to 'https://login.windows.net/{authority-guid}/oauth2/authorize?response_type=id_token&redirect_uri=....etc..etc..', which is disallowed for cross-origin requests that require preflight.

示例 header (匿名):

RequestOPTIONS /api/items HTTP/1.1Host: webapi.azurewebsites.netConnection: keep-aliveAccess-Control-Request-Method: GETAccess-Control-Request-Headers: accept, authorizationOrigin: https://mvcapp.azurewebsites.netUser-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36Accept: */*Referer: https://mvcapp.azurewebsites.net/ResponseHTTP/1.1 302 FoundContent-Length: 504Location: 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...Server: Microsoft-IIS/8.0X-Powered-By: ASP.NETSet-Cookie: ARRAffinity=4f51...snip....redact....db6d;Path=/;Domain=webapi.azurewebsites.net

What I've done/tried

  1. Ensured the Azure AD tenant allows OAuth2 implicit flow as described here and elsewhere.
  2. Ensured that the API exposes access permissions and that the MVC/SPA registers for access using those exposed permissions.
  3. Explicitly added an OPTIONS verb handler in the API's web.config (see below).
  4. Used various combinations of enabling CORS on the API server, OWIN by itself and also with EnableCorsAttribute (see below).

Questions

Is there any way to have a Web API associated with an Azure AD tenant not redirect on CORS preflight requests?Am I missing some initialization setup in the adal.js library and/or OWIN startup code (see below)?Are there settings in the Azure portal that will allow OPTIONS requests through to the OWIN pipeline?

Relevant code:

adal.js initialization

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 选项动词处理程序注册

<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 示例代码中的几乎每一种可以想象到的组合。

  1. ADAL JavaScript and AngularJS – Deep Dive
  2. Secure ASP.NET Web API 2 using Azure Active Directory, Owin Middleware, and ADAL
  3. Token Based Authentication using ASP.NET Web API 2, Owin, and Identity
  4. AzureADSamples/SinglePageApp-DotNet (github)
  5. AngularJSCORS (github)
  6. How to make CORS Authentication in WebAPI 2?
  7. AngularJS and OWIN Authentication on WebApi

最佳答案

我也遇到了类似的问题,无法找到合适的软件包。只需要设置 Owin cors 即可。请先检查 owin.cors 的软件包。

<package id="Microsoft.Owin" version="3.0.0" targetFramework="net45" />
<package id="Microsoft.Owin.Cors" version="2.1.0" targetFramework="net45" />

处理程序的 WebConfig 选项:

<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

您在 owin 配置中指定 cors 选项是正确的。

 public void ConfigureAuth(IAppBuilder app)
{
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
new WindowsAzureActiveDirectoryBearerAuthenticationOptions
{
Audience = ConfigurationManager.AppSettings["ida:Audience"],
Tenant = ConfigurationManager.AppSettings["ida:Tenant"]

});
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
}

Controller 不需要CORS相关属性。

   [Authorize]
public class ContactsController : ApiController
{

// GET api/<controller>
public IEnumerable<string> Get()
{
return new string[] { "person1", "person2" };
}

// GET api/<controller>/5
public string Get(int id)
{
return "person" + id;
}

WebAPIConfig不需要CORS相关条目。

工作示例在这里:https://github.com/omercs/corsapisample

您可以使用以下代码在您的应用中进行测试:

app.factory('contactService', ['$http', function ($http) {
var serviceFactory = {};

var _getItems = function () {
$http.defaults.useXDomain = true;
delete $http.defaults.headers.common['X-Requested-With'];
return $http.get('http://yourhostedpage/api/contacts');
};

serviceFactory.getItems = _getItems;

return serviceFactory;

}]);

飞行前响应示例:

Remote Address:127.0.0.1:8888
Request URL:http://localhost:39725/api/contacts
Request Method:OPTIONS
Status Code:200 OK
Request Headersview source
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, authorization
Access-Control-Request-Method:GET
Host:localhost:39725
Origin:http://localhost:49726
Proxy-Connection:keep-alive
Referer:http://localhost:49726/myspa.html
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36
Response Headersview source
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:authorization
Access-Control-Allow-Origin:http://localhost:49726
Content-Length:0
Date:Fri, 23 Jan 2015 01:10:54 GMT
Server:Microsoft-IIS/8.0
X-Powered-By:ASP.NET

关于angularjs - CORS 预检请求在 Azure 托管 Web API 中通过 302 重定向进行响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28097648/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com