簡體   English   中英

無法在 ASP.NET Core 2 應用程序上注銷 identityserver4 的 OpenIdConnect 身份驗證

[英]Cannot sign out the OpenIdConnect authentication of identityserver4 on ASP.NET Core 2 application

我的身份服務器使用的是 identityserver4 框架( http://localhost:9000 )。 我在身份服務器上注冊客戶端,如下所示。

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" }
     });  

這是我的客戶端應用程序 ( http://localhost:60001 ) 上的身份驗證。

private void AddAuthentication(IServiceCollection services)
{
    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = "Cookies";
        options.DefaultChallengeScheme = "oidc";       
    })
    .AddCookie()
    .AddOpenIdConnect("oidc", options =>
    {
        Configuration.GetSection("OpenIdConnect").Bind(options);        
    });    
}    

"OpenIdConnect": {
    "SignInScheme": "Cookies",
    "Authority": "http://localhost:9000/",
    "RequireHttpsMetadata": false,
    "ClientId": "customer.api",
    "ClientSecret": "testsecret",
    "Scope": [ "customerprivatelinesvn.api", "offline_access" ],
    "CallbackPath": "/signin-oidc",
    "ResponseType": "code id_token token",
    "GetClaimsFromUserInfoEndpoint": true,
    "SaveTokens": true
  }

客戶端應用程序的 HomeController

[Authorize]
public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }    
}

這是用戶登錄后客戶端應用程序的 Cookie。 在此處輸入圖片說明

我嘗試執行如下注銷操作

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

        return RedirectToAction("Index", "Home");                  
    }
}

但是當用戶退出時,它不會調用身份服務器的 endsession 端點。 我看fiddler的流量,沒有對身份服務器的請求。

在此處輸入圖片說明

我的期望是當用戶退出時,它會調用身份服務器的 endsession 端點並重定向到身份服務器的注銷鏈接,如下所示。

在此處輸入圖片說明

在此處輸入圖片說明

我們可以通過調用 OwinContext signout 在 MVC 應用程序上輕松完成此操作

private void LogoutOwin(IOwinContext context)
        {
            context.Authentication.SignOut();
        }

但是注銷方法在 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>

要允許注銷,請使用以下注銷操作:

public async Task Logout()
{
    await HttpContext.SignOutAsync("Cookies");
    await HttpContext.SignOutAsync("oidc");
}

這正是快速入門所說的使用( http://docs.identityserver.io/en/release/quickstarts/3_interactive_login.html )。 你(和我)太聰明了。 我查看了教程中的操作並認為“這還沒有完成,它沒有返回操作結果,讓我們重定向回我的頁面”。

實際上發生的是HttpContext.SignOutAsync("oidc"); 設置默認 ActionResult(即重定向到 OpenIdConnect 提供程序以完成注銷)。 通過指定你自己的return RedirectToAction("Index", "Home"); 你覆蓋它,所以注銷操作永遠不會發生。

注銷后重定向

根據此答案,您在注銷完成后指定重定向 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);
}

在 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");
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM