CORS预检请求在Azure托管的Web API中响应302重定向

布赖恩

设想:

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

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

  2. 带有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

我做过/尝试过的

  1. 确保Azure AD租户允许OAuth2隐式流,如此和其他地方所述。
  2. 确保API公开访问权限,并确保MVC / SPA使用这些公开权限注册访问权限。
  3. 在API的web.config中明确添加了OPTIONS动词处理程序(请参见下文)。
  4. 在API服务器,OWIN本身以及EnableCorsAttribute(请参见下文)上使用了启用CORS的各种组合。

问题

有什么方法可以使与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示例代码中几乎所有可以想象的组合。

  1. ADAL JavaScript和AngularJS –深入研究
  2. 使用Azure Active Directory,Owin中间件和ADAL保护ASP.NET Web API 2的安全
  3. 使用ASP.NET Web API 2,Owin和身份的基于令牌的身份验证
  4. AzureADSamples / SinglePageApp-DotNet(github)
  5. AngularJSCORS(github)
  6. 如何在WebAPI 2中进行CORS身份验证?
  7. WebApi上的AngularJS和OWIN身份验证
布赖恩

解决(某种)

这似乎是由部署问题引起的,尤其是最初将应用程序发布到Azure的方式。这两个应用程序最初都是使用Windows身份验证编写的,并已部署到标准(即非Azure)Web服务器上。使用这些技术,这些应用程序可以按预期工作。

根据新的业务需求,我一直在努力将其迁移到Azure。我遵循的过程是:

  1. 按照最初编写的方式,将两个应用程序从Visual Studio 2013发布向导直接部署/发布到Azure。当然,这如预期的那样破裂了,因为他们无法从Azure内部与本地Active Directory通信。
  2. 根据问题末尾所有链接的详细信息,逐渐更新代码以删除Windows Auth并替换为Azure AD auth。
  3. 使用Azure AD门户将应用程序与Azure AD租户手动关联以进行身份​​验证。

有时,我注意到VS Publish向导的“设置”选项卡上的“启用组织身份验证”选项,并开始使用它来将应用程序与租户关联。因为我已经手动关联了它们,所以Visual Studio最终为每个应用程序创建了另一个Azure AD应用程序,结果是两个。

最后,这是做什么的:

  1. 使用门户网站删除了两个应用程序的所有Azure记录,删除了Azure网站本身以及Azure AD站点/关联。
  2. 将两个应用程序中的所有代码更改恢复到其原始状态。
  3. 在应用程序中重新实现了Azure AD身份验证(OWIN,adal.js等)。
  4. 是否同时发布了这两个应用程序,以使VS向导可以处理所有Azure关联。
  5. 使用新创建的客户端ID更新了Web.config文件和adal.js初始化。
  6. 再次发布。

现在,选项预检请求不再是302重定向。

相反,它们现在是405 Method Not Allowed,与该线程非常相似进步,某种程度上。

即使它仍然不能端到端地工作,我也将保留此答案(而不是删除问题),以防它可能帮助其他经历Azure 302重定向的CORS预检的人。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

.NET Web API CORS预检请求

来自分类Dev

带有CORS预检选项请求的Ajax防伪POST(302重定向)

来自分类Dev

带有CORS预检选项请求的Ajax防伪POST(302重定向)

来自分类Dev

Python请求:如何从302重定向获取响应Cookie

来自分类Dev

ASP.Net/ASP.NET Core Web API的未授权请求返回302重定向响应,而不是401

来自分类Dev

端点接受参数时,CORS对预检请求的响应

来自分类Dev

Laravel 5 REST API JSONP CORS请求获取错误302重定向到'/'

来自分类Dev

外部 API 未处理 CORS 预检请求

来自分类Dev

Spring Data REST中的CORS预检请求

来自分类Dev

带有预检和重定向的CORS请求:不允许。解决方法?

来自分类Dev

角度,对预检请求的响应

来自分类Dev

带有Angular前端的Web Api OAuth-无法处理302重定向

来自分类Dev

Codeigniter 4中的CORS问题:对预检请求的响应未通过访问控制检查

来自分类Dev

OAuth 中的 CORS:对预检请求的响应未通过访问控制检查

来自分类Dev

是否可以将请求标头添加到CORS预检请求中?

来自分类Dev

luaSocket HTTP请求始终以重定向响应(301或302)

来自分类Dev

具有Windows身份验证的已启用CORS ASP.NET Web API 2应用程序中的预检请求

来自分类Dev

Istio 1.5 Cors无法正常工作-对预检请求的响应未通过访问控制检查

来自分类Dev

401对针对Springboot服务器的CORS预检OPTIONS请求的响应

来自分类Dev

源已被 CORS 策略阻止对预检请求的响应未通过访问控制检查

来自分类Dev

XMLHttpRequest CORS到Google Cloud Storage仅在预检请求中起作用

来自分类Dev

无效的预检CORS请求,因为标头“ content-type”不在:allow_headers中

来自分类Dev

返回哪些Access-Control- *标头以响应CORS预检OPTIONS请求,然后响应随后的GET / POST / etc。请求?

来自分类Dev

对预检请求的响应未通过?

来自分类Dev

节点 JS - CORS - 预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段授权

来自分类Dev

被 CORS 策略阻止:预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段授权

来自分类Dev

VB.NET Web API CORS PUT预检405错误

来自分类Dev

CORS-对预检请求的响应未通过访问控制检查:它没有HTTP正常状态

来自分类Dev

CORS 策略:对预检请求的响应未通过访问控制检查:它没有 HTTP ok 状态

Related 相关文章

  1. 1

    .NET Web API CORS预检请求

  2. 2

    带有CORS预检选项请求的Ajax防伪POST(302重定向)

  3. 3

    带有CORS预检选项请求的Ajax防伪POST(302重定向)

  4. 4

    Python请求:如何从302重定向获取响应Cookie

  5. 5

    ASP.Net/ASP.NET Core Web API的未授权请求返回302重定向响应,而不是401

  6. 6

    端点接受参数时,CORS对预检请求的响应

  7. 7

    Laravel 5 REST API JSONP CORS请求获取错误302重定向到'/'

  8. 8

    外部 API 未处理 CORS 预检请求

  9. 9

    Spring Data REST中的CORS预检请求

  10. 10

    带有预检和重定向的CORS请求:不允许。解决方法?

  11. 11

    角度,对预检请求的响应

  12. 12

    带有Angular前端的Web Api OAuth-无法处理302重定向

  13. 13

    Codeigniter 4中的CORS问题:对预检请求的响应未通过访问控制检查

  14. 14

    OAuth 中的 CORS:对预检请求的响应未通过访问控制检查

  15. 15

    是否可以将请求标头添加到CORS预检请求中?

  16. 16

    luaSocket HTTP请求始终以重定向响应(301或302)

  17. 17

    具有Windows身份验证的已启用CORS ASP.NET Web API 2应用程序中的预检请求

  18. 18

    Istio 1.5 Cors无法正常工作-对预检请求的响应未通过访问控制检查

  19. 19

    401对针对Springboot服务器的CORS预检OPTIONS请求的响应

  20. 20

    源已被 CORS 策略阻止对预检请求的响应未通过访问控制检查

  21. 21

    XMLHttpRequest CORS到Google Cloud Storage仅在预检请求中起作用

  22. 22

    无效的预检CORS请求,因为标头“ content-type”不在:allow_headers中

  23. 23

    返回哪些Access-Control- *标头以响应CORS预检OPTIONS请求,然后响应随后的GET / POST / etc。请求?

  24. 24

    对预检请求的响应未通过?

  25. 25

    节点 JS - CORS - 预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段授权

  26. 26

    被 CORS 策略阻止:预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段授权

  27. 27

    VB.NET Web API CORS PUT预检405错误

  28. 28

    CORS-对预检请求的响应未通过访问控制检查:它没有HTTP正常状态

  29. 29

    CORS 策略:对预检请求的响应未通过访问控制检查:它没有 HTTP ok 状态

热门标签

归档