asp.net-core - 从 Angular 5 注销 MVC 应用程序

标签 asp.net-core angular5 identityserver4 logout

我们有一个基于 MVC 身份验证构建的 Angular 5 应用程序。该应用程序由 Home/Index 操作提供,一旦加载应用程序,角度路由就会处理几乎所有事情。我们这样做主要是因为我们想要使用 MVC 的身份验证流程(我们使用 Identity Server 4 作为我们的 Oath 系统)。

这很有效,但有一个异常(exception):注销。当我们尝试注销时,应用程序似乎立即重新授权并重新加载,而不是返回到 Identity Server 登录页面。

最初,我们通过以下代码在开发环境中取得了成功:

[HttpPost]
public async Task<IActionResult> Logout()
{
  foreach (string key in Request.Cookies.Keys)
  {
    Response.Cookies.Delete(key);
  }

  await HttpContext.SignOutAsync();

  return Ok();
}

但这是一个误报,因为我们所有的应用程序都在本地主机上运行,​​因此它们可以访问彼此的 cookie。因此,Identity Server cookie 与 Angular 应用程序的 cookie 一起被清除。

我们尝试用这样的逻辑替换该逻辑:

    public async Task Logout()
    {
        if (User?.Identity.IsAuthenticated == true)
        {
            // delete local authentication cookie
            await HttpContext.SignOutAsync("Cookies");
            await HttpContext.SignOutAsync("oidc");
        }
    }

但是,它在这两种环境中都没有注销(但是该代码适用于我们使用相同身份服务器的 MVC 应用程序之一)。

为了提供一些背景知识,我们的 Angular 应用程序的注销过程来自一个 Material 菜单,然后在调用注销函数之前,我们会在其中提示用户是否确实想使用模式注销。该过程的代码片段:

注销按钮调用的方法:

public openDialog(): void {
    let dialogRef = this.dialog.open(ModalComponent, {
      width: '250px',
      data: { text: this.logoutText, ok: this.okText, cancel: this.cancelText }
    });

    dialogRef.afterClosed().subscribe(result => {
      if (result !== undefined) {
        switch (result.data) {
          case 'ok':
            this.logout();
            break;
          case 'cancel':
            break;
          default:
            break;
        }
      }
   });
}

private logout(): void {
   this.sessionService.logOut();
}

session 服务:

public logOut(): void {
    this.auth.revokeToken();
    this.http.post(this.logoutUrl, undefined).subscribe(x => window.location.reload());
}

如上所述,以这种方式调用注销最终会导致页面刷新,并且用户并未真正注销。我们可能缺少一些简单的东西,但到目前为止我所做的所有修改都没有取得任何成功。

编辑:

我们的角度路由相当简单(尽管路径阻止我们调用诸如 home/logout 之类的东西):

{
  path: 'parts',
  component: PartsComponent,
  canActivate: [AuthGuard],
  runGuardsAndResolvers: 'always',
  data: { title: 'Parts' }
},
{
  path: '',
  redirectTo: 'parts',
  pathMatch: 'full'
},
{
  path: '**',
  redirectTo: 'parts'
}

我们的 MVC 路线也相当简单

    app.UseMvc(routes =>
    {
      routes.MapRoute(
       name: "default",
       template: "{controller=Home}/{action=Index}/{id?}");

      routes.MapRoute(
       "Sitemap",
       "sitemap.xml",
       new { controller = "Home", action = "SitemapXml" });

      routes.MapSpaFallbackRoute(
        name: "spa-fallback",
        defaults: new { controller = "Home", action = "Index" });
    });

我不确定我们如何使用角度路线轻松地路由到主页/注销。我猜我们必须为其添加一条路线。我们曾经尝试过这一点,但它从未正确路由。我正在尝试查找有关我们尝试过的内容的笔记。

最佳答案

清除应用程序的本地 Cookie 后,将用户发送至 Idsrv 的 end_session_endpoint。 (您显示的用于清除 session 的代码应该可以工作,如果没有,我会在startup.cs中进行配置并进行调试以检查重定向是否确实删除了浏览器中的cookie)。

例如https://demo.identityserver.io/.well-known/openid-configuration

您可以在此处看到端点。这应该删除 Idsrv 上的 session 。根据您的设置,这可能会终止使用同一 Identity Server 实例的其他应用程序上的 session 。

您可以在docs中阅读更多相关信息。 .

我没有发现 Angular 路由存在干扰服务器端路由的问题。当然,只要您确实使用常规 window.location.replace

重定向到该页面即可

当然,就像@Win提到的那样,如果您使用refresh_token和reference_tokens,那么撤销它们将是一个很好的安全指南。

关于asp.net-core - 从 Angular 5 注销 MVC 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51539867/

相关文章:

c# - 使用 TestServer 在 AspNetCore 中的集成测试中模拟和解决 Autofac 依赖性

c# - Controller 位于区域中的 RedirectToAction

c# - 将 Asp.net Core 中的 CultureInfo 设置为具有 .作为 CurrencyDecimalSeparator 而不是 ,

javascript - Material Angular 表多行指令

angular - 将变量传递给 ng-container 元素

c# - 自动刷新 Blazor 中的组件

angular5 - Angular 5无法从组件函数将数据设置为ngmodel

c# - 在 Application Insights 中查找 IdentityServer4 错误

asp.net-core - IdentityServer4 中的 AddSigningCredential - 自签名或来自证书颁发机构

identityserver4 - 如何将自定义身份验证提供程序集成到 IdentityServer4