C# 无法注销ASP.NET Core 2应用程序上IdentityServer 4的OpenIdConnect身份验证

C# 无法注销ASP.NET Core 2应用程序上IdentityServer 4的OpenIdConnect身份验证,c#,asp.net-core-2.0,identityserver4,C#,Asp.net Core 2.0,Identityserver4,我的Identity Server正在使用Identity Server 4 framework()。我在Identity Server上注册客户端,如下所示 clients.Add( new Client { ClientId = "customer.api", ClientName = "Customer services", AllowedGrantTypes = GrantTypes.HybridAndClient

我的Identity Server正在使用Identity Server 4 framework()。我在Identity Server上注册客户端,如下所示

clients.Add(
     new Client
     {
         ClientId = "customer.api",
         ClientName = "Customer services",
         AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
         RequireConsent = false,
         AllowAccessTokensViaBrowser = true,

         RedirectUris = { "http://localhost:60001/signin-oidc" },
         PostLogoutRedirectUris = { "http://localhost:60001/signout-callback-oidc" },
         ClientSecrets = new List<Secret>
         {
             new Secret("testsecret".Sha256())
         },
         AllowedScopes = new List<string>
         {
             IdentityServerConstants.StandardScopes.OpenId,
             IdentityServerConstants.StandardScopes.Profile,
             IdentityServerConstants.StandardScopes.Email,
             IdentityServerConstants.StandardScopes.OfflineAccess,
             "customerprivatelinesvn.api",                        
         },
         AllowOfflineAccess = true,
         AlwaysIncludeUserClaimsInIdToken = true,
         AllowedCorsOrigins = { "http://localhost:60001" }
     });  
客户端应用程序的HomeController

[Authorize]
public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }    
}
以下是用户登录后客户端应用的Cookies。

我尝试执行以下注销操作

public class AccountController : Controller
{
    public async Task<IActionResult> Signout()
    {
        await HttpContext.SignOutAsync("Cookies");
        await HttpContext.SignOutAsync("oidc");

        return RedirectToAction("Index", "Home");                  
    }
}
但是签出方法在ASP.NET Core 2上不再有效

注意:我在AJAX帖子中调用注销操作,因为我的客户端应用程序是angular 5应用程序

有人知道如何在ASP.NET Core 2上正确实现注销吗

多谢各位

问候,


凯文

我现在可以解决我的问题了

1) 返回SignOutResult将调用endsession端点

2) 将AJAX帖子更改为提交表单

public class AccountController : Controller
{
    public IActionResult Signout()
    {
        return new SignOutResult(new[] { "oidc", "Cookies" });            
    }
}


<form action="/Account/Signout" id="signoutForm" method="post" novalidate="novalidate">
    <ul class="nav navbar-nav navbar-right">
        <li><a href="javascript:document.getElementById('signoutForm').submit()">Sign out</a></li>
    </ul>
</form>
公共类AccountController:控制器
{
公共IActionResult签出()
{
返回新的SignOutResult(新[]{“oidc”,“Cookies”});
}
}

在Net Core 2.0上更改代码以使用枚举CookieAuthenticationDefaults和OpenIdConnectDefaults

    services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
        })
        .AddCookie()
        .AddOpenIdConnect(SetOpenIdConnectOptions);


private static void SetOpenIdConnectOptions(OpenIdConnectOptions options)
{
    options.ClientId = "auAuthApp_implicit";
    options.Authority = "http://localhost:55379/";

    options.SignInScheme = "Cookies";
    options.RequireHttpsMetadata = false;

    options.SaveTokens = true;
    options.ResponseType = "id_token token";
    options.GetClaimsFromUserInfoEndpoint = true;

}
而且

public async Task<IActionResult> Logout()
{
    await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);

    return RedirectToAction("Index", "Home");
}
public异步任务注销()
{
等待HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
等待HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
返回重定向到操作(“索引”、“主页”);
}

要允许注销,请使用以下注销操作:

public async Task Logout()
{
    await HttpContext.SignOutAsync("Cookies");
    await HttpContext.SignOutAsync("oidc");
}
这正是quickstart所说的使用()。 你(和我)太聪明了。我查看了教程中的操作,认为“这还不完整,它不会返回操作结果,让我们重定向回我的页面”

实际上发生的是
HttpContext.SignOutAsync(“oidc”)设置默认的ActionResult(即重定向到OpenIdConnect提供程序以完成注销)。通过使用
return RedirectToAction(“索引”、“主页”)指定您自己的您将覆盖此选项,因此注销操作永远不会发生

注销后重定向 从中,在注销完成后指定重定向URL的方式是使用AuthenticationProperties

public async Task Logout()
{
   await context.SignOutAsync("Cookies");
   var prop = new AuthenticationProperties
   {
       RedirectUri = "/logout-complete"
   };
   // after signout this will redirect to your provided target
   await context.SignOutAsync("oidc", prop);
}

我尝试了这个方法(这似乎只是更改了身份验证方案的显示名称),但仍然存在相同的问题调用
控制器。注销
会生成一个
SignOutResult
对象,然后可以从
IActionResult
控制器操作返回该对象。然后,
SignOutResult
类调用
httpcontextensions.SignOutAsync
。直接从控制器操作中调用
httpcontextensions.SignOutAsync
不是一个好主意。
public async Task Logout()
{
    await HttpContext.SignOutAsync("Cookies");
    await HttpContext.SignOutAsync("oidc");
}
public async Task Logout()
{
   await context.SignOutAsync("Cookies");
   var prop = new AuthenticationProperties
   {
       RedirectUri = "/logout-complete"
   };
   // after signout this will redirect to your provided target
   await context.SignOutAsync("oidc", prop);
}