trying to call the backend api from angular frontend but can't authenticate with azure AD because of cors preflight access-control-allow-orgin issue

huangapple go评论64阅读模式
英文:

trying to call the backend api from angular frontend but can't authenticate with azure AD because of cors preflight access-control-allow-orgin issue

问题

我的系统是Angular客户端,后端使用.NET Core。我试图将身份验证过程迁移到Azure AD,以遵循我的企业SSO。在客户端启用Azure AD后,使用MSAL,在后端遵循OIDC。从客户端我可以成功登录并将令牌存储在本地存储中,甚至可以调用Graph API检索一些信息,所有这些都很顺利,来自客户端。然而,我无法从Angular客户端调用我的后端API,因为我总是遇到以下问题:

Access to XMLHttpRequest at 'https://login.microsoftonline.com/{tenantID}/oauth2/v2.0/authorize?client_id=XXX'(从'https://localhost:44328/api/CutOffdate/AreRequestsAllowed'重定向)来自' https://localhost:44328'的来源已被CORS策略阻止:对预检请求的响应未通过访问控制检查:在请求的资源上未出现'Access-Control-Allow-Origin'标头

我花了很多时间调整startup.cs中的CORS策略,启用了任何来源、任何标头以及指定特定域的任何方法,但迄今为止没有成功绕过这个错误。我确保了app.usecors和app.usemvc的顺序。我检查并尝试了很多解决方案,但仍然没有成功。这是Azure AD的问题吗?我是否需要在Angular客户端上执行与CORS相关的操作?请注意预检部分。

我试图从Angular前端调用后端API,但由于CORS预检访问控制允许来源的问题,无法使用Azure AD进行身份验证。

英文:

my system is angular client side and .net core backend. i'm trying to migrate the authentication process to azure AD to follow my corporate's SSO. after enabling Azure AD on client side using MSAL and on the backend following OIDC. from the client side i can login successfully and store the token in the local storage, even calling graph Api for some info retrieving and all of that is smooth and from client side. however I can't call my backend API from the angular client as I always get

Access to XMLHttpRequest at 'https://login.microsoftonline.com/{tenantID}/oauth2/v2.0/authorize?client_id=XXX' (redirected from 'https://localhost:44328/api/CutOffdate/AreRequestsAllowed') from origin 'https://localhost:44328' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource

i spent a lot of time playing with the startup.cs cors policy and enabling any origin and any header with any method of specifying the certain domain but no luck so far i'm not able to bypass that error. i made sure of the order of app.usecors and app.usemvc. i checked and tried a lot of solutions but still no luck. is it issue from Azure AD? do i need to do something relating to cors on the angular client? please note the **preflight **part.

trying to call the backend api from the angular frontend but can't authenticate with azure AD because of cors preflight access-control-allow-orgin issue

答案1

得分: 0

根据错误消息,似乎您的应用程序重定向到Microsoft身份验证登录页面,然后遇到了CORS问题。然而,当我们有一个客户端应用程序并使用它来调用后端API时,不应该重定向到登录页面进行身份验证。所以我担心您的后端应用程序可能是一个MVC应用程序,或者您有类似这样的代码 builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme).AddMicrosoftIdentityWebApp(builder.Configuration) 来集成Azure AD。请注意,这是 AddMicrosoftIdentityWebApp,不同于 AddMicrosoftIdentityWebApi。您可以查看这两份文档。有关Azure AD Web应用程序,以及有关Azure AD Web API

如果您的后端服务是一个ASP.NET Core Web API,那么您只需按照我分享的第二个链接所属的教程来注册Azure AD应用程序,公开API并更改您的代码。

如果您的后端服务是一个ASP.NET Core Web应用程序,并且您还希望保留登录过程,那么您必须添加两个身份验证方案,如下所示的代码:

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));

builder.Services.AddControllersWithViews().AddMicrosoftIdentityUI();

假设您有一个控制器来返回View(),然后使用Authorize属性,像这样,它将使匿名请求重定向到登录页面:

[Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)]
public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}

假设您有一个API控制器,您需要使用以下属性,以使没有正确访问令牌的请求返回401/403错误:

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Route("api/[controller]")]
[ApiController]
[RequiredScope("your_custom_api_scope_name")]
public class DataController : ControllerBase
{
    public string Get() {
        return "hello";
    }
}
英文:

According to the error message, it seems that your app redirect to the microsoft identity login page then you got cors issue. However, when we have a client app and use it to call backend API, it shouldn't redirect to sign in page to get authentication. So I'm afraid your backend app is an MVC app or you have code like this builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme).AddMicrosoftIdentityWebApp(builder.Configuration) to integrate Azure AD. Pls note this is AddMicrosoftIdentityWebApp which is different from AddMicrosoftIdentityWebApi. You can have a look at this 2 documents. For Azure AD web app. And for Azure AD web api.

If what you have for the backend service is an asp.net core web api, then you can just follow the tutorial which the second link I shared belongs to to register azure ad app, expose api and change your code.

If what you have for the backend service is an asp.net core web app, and you also want to remain the sign in process at the same time, then you have to add 2 authentication scheme like code below.

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));

builder.Services.AddControllersWithViews().AddMicrosoftIdentityUI();

Assuming you have a controller to return View(), then use Authorize attribute like this, it will make anonymous request redirect to sign in page.

[Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)]
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

And assuming you have an api controller, you need to use attribute like this to make the request without correct access token returning 401/403 error:

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
    [Route("api/[controller]")]
    [ApiController]
    [RequiredScope("your_custom_api_scope_name")]
    public class DataController : ControllerBase
    {
        public string Get() {
            return "hello";
        }
    }

huangapple
  • 本文由 发表于 2023年5月28日 23:58:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76352354.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定