首页 文章

无法在ASP.NET Core 2应用程序上注销identityserver4的OpenIdConnect身份验证

提问于
浏览
3

我的Identity Server使用的是identityserver4框架(http://localhost:9000) . 我在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" }
     });

这是我的客户端应用程序(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 of client app

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

以下是用户登录后的客户端应用程序Cookie .
enter image description here

我尝试实施如下的退出操作

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

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

但是当用户注销时,它不会调用身份服务器的endsession endpoints . 我看看小提琴手的流量,没有要求身份识别服务器 .

enter image description here

我的期望是当用户注销时,它将调用身份服务器的endsession endpoints 并重定向到身份服务器的注销链接,如下所示 .

enter image description here

enter image description here

我们可以通过调用OwinContext注销在MVC应用程序上轻松完成此操作

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

但是,注销方法在ASP.NET Core 2上不再起作用 .

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

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

非常感谢你 .

问候,

凯文

3 回答

  • 0

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

    1)返回SignOutResult将调用endsession endpoints .

    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>
    
  • 8

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

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

    这正是快速入门所说的(http://docs.identityserver.io/en/release/quickstarts/3_interactive_login.html) . 你(和我)太聪明了 . 我查看了教程中的操作,并认为'That'未完成,它没有't return an action result, lets redirect back to my page' .

    实际上会发生什么 HttpContext.SignOutAsync("oidc"); 设置一个默认的ActionResult(它将重定向到OpenIdConnect提供程序以完成注销) . 通过使用 return RedirectToAction("Index", "Home"); 指定您自己,您可以覆盖它,因此注销操作永远不会发生 .

    注销后重定向

    this answer开始,在注销完成后指定重定向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);
    }
    
  • 6

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

相关问题