Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在“上提供授权保护SPA”/&引用;在使用azure auth之前使用BFF和自定义登录屏幕_C#_Angular_Asp.net Core_Authentication_Azure Active Directory - Fatal编程技术网

C# 在“上提供授权保护SPA”/&引用;在使用azure auth之前使用BFF和自定义登录屏幕

C# 在“上提供授权保护SPA”/&引用;在使用azure auth之前使用BFF和自定义登录屏幕,c#,angular,asp.net-core,authentication,azure-active-directory,C#,Angular,Asp.net Core,Authentication,Azure Active Directory,我意识到这个问题听起来很长很复杂!我会尽力解释的。 我有一个ASP.NET Core 5应用程序,它是我的Angular应用程序的BFF(前端后端)。您必须使用Azure AD登录才能访问SPA。其结果保存在cookie中,因此我们有两个身份验证方案(Azure AD和cookie)。图像等资源无需经过身份验证即可访问 问题是我有一个HomeController,它有一个Index()操作,该操作有一个[AuthorizeForScopes]和[authorized]属性,用于检查用户是否登录并

我意识到这个问题听起来很长很复杂!我会尽力解释的。 我有一个ASP.NET Core 5应用程序,它是我的Angular应用程序的BFF(前端后端)。您必须使用Azure AD登录才能访问SPA。其结果保存在cookie中,因此我们有两个身份验证方案(Azure AD和cookie)。图像等资源无需经过身份验证即可访问

问题是我有一个HomeController,它有一个
Index()
操作,该操作有一个
[AuthorizeForScopes]
[authorized]
属性,用于检查用户是否登录并授权了作用域。如果没有,则
AuthorizeForScopes
将把它们带到Microsoft登录页面。如果他们已登录,该方法将重定向到SPA运行的
/home

此设置存在一些问题:

  • 我希望SPA在
    /
    • 无法执行此操作,因为
      HomeController.Index()
      方法在那里运行
    • 使用类似于
      returnphysicalfile(..)
      的方法不是一个很好的解决方案;在开发过程中,由于Web包代理等原因,路径不同。。。在生产过程中,由于某些原因,SPA没有正确加载
  • 如果用户没有登录,我想显示一个服务器端呈现的登录屏幕,它充当应用程序的“介绍页面”。它显示一个“使用MS登录”按钮,该按钮将触发MS登录。
    • 这不起作用,因为
      [Authorize]
      [AuthorizeForScopes]
      标记会立即将用户带到MS登录屏幕
这两件事我都做不好。下面是一些代码来解释原因:

家庭控制器

[Route("/")]
public class HomeController : Controller
{
    [HttpGet]
    [Authorize]
    [AuthorizeForScopes(ScopeKeySection = "Scopes")]
    public IActionResult Index()
    {
        // We can't run the SPA on "/" because we need to intercept that here to require that the user is authorized before accessing the SPA.
        return Redirect("/home");
    }
}

重要中间件

// This is done AFTER useStaticFiles(), useEndpoints() and useSpaStaticFiles()

// Redirect the user to authenticate if the user isnt at this moment
// All static frontend related files are served using the UseSpaStaticFiles middleware
// What's left is the index.html
app.Use(async (context, next) =>
{
    if (context.User?.Identity?.IsAuthenticated != true)
    {
        await context.ChallengeAsync(WellKnownAuthenticationSchemes.OpenIdConnect);
    }
    else
    {
        await next();
    }
});


认证

//省略了其他一些身份验证配置;这不重要。
services.Configure(“Cookie”,opt=>
{
opt.Cookie.IsEssential=true;
opt.Cookie.Name=“auth”;
opt.Cookie.SameSite=SameSiteMode.Lax;//由于signin oidc回调的跨原点性质,需要此选项
opt.Cookie.SecurePolicy=Environment.IsDevelopment()
?CookieSecurePolicy.SameAsRequest
:厨师安全政策。始终;
opt.Cookie.HttpOnly=true;
opt.SlidingExpiration=true;
opt.ExpireTimeSpan=TimeSpan.FromDays(90);
});
服务。添加身份验证(“Cookie”);
服务
.AddMicrosoftIdentityWebAppAuthentication(配置、,
cookieScheme:“饼干”)
.EnableTokenAcquisitionTollDownstreamAPI(Configuration.GetValue(“Scopes”).Split(“”)
.AddDistributedTokenCaches();

因此,总结一下:

  • 如果用户未登录/未授权可能在
    /login
    上运行的作用域,我想显示一个自定义登录屏幕,然后按该页面上的按钮运行当前在
    索引()上的
    [Authorize]
    [AuthorizeForScopes]
    逻辑
  • 我希望SPA在
    /
    上运行,并且只有在用户登录并授权了作用域后才能访问
我将非常感谢你的帮助

// Some other auth config is left out; it's not important.

services.Configure<CookieAuthenticationOptions>("Cookie", opt =>
{
    opt.Cookie.IsEssential = true;
    opt.Cookie.Name = "auth";
    opt.Cookie.SameSite = SameSiteMode.Lax; // Required due to cross origin nature of signin-oidc callback
    opt.Cookie.SecurePolicy = Environment.IsDevelopment()
        ? CookieSecurePolicy.SameAsRequest
        : CookieSecurePolicy.Always;
    opt.Cookie.HttpOnly = true;
    opt.SlidingExpiration = true;
    opt.ExpireTimeSpan = TimeSpan.FromDays(90);
});


services.AddAuthentication("Cookie");

services
    .AddMicrosoftIdentityWebAppAuthentication(Configuration,
        cookieScheme: "Cookie")
    .EnableTokenAcquisitionToCallDownstreamApi(Configuration.GetValue<string>("Scopes").Split(" "))
    .AddDistributedTokenCaches();