IdentityServer3注销功能不适用于ASP.NET Core客户端

时间:2017-03-08 22:14:40

标签: asp.net-mvc-5 asp.net-core owin identityserver3 openid-connect

我使用IdentityServer 3进行身份验证。我有2个客户端应用程序,一个使用经典的ASP.NET MVC 5开发,另一个使用ASP.NET Core。两个应用程序都具有如下实现的注销功能:

经典ASP.NET MVC 5

应用程序启动

public class Startup
{
    public void Configuration(IAppBuilder app)
    {        
        var CK = new CookieAuthenticationOptions()
        {
            AuthenticationType = "Cookies",
            CookieName = "MyCookie"
        };

        app.UseCookieAuthentication(CK);

        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            Authority = "https://login.mydomain.com/identity",
            Scope = "openid profile",
            ClientId = "myclientid",
            RedirectUri = "http://localhost:34937/",
            ResponseType = "id_token",
            SignInAsAuthenticationType = "Cookies",

            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                SecurityTokenValidated = (context) =>
                {
                    // do claim transformation here
                },

                RedirectToIdentityProvider = (n) =>
                {
                    if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
                    {
                        var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token").Value;
                        n.ProtocolMessage.IdTokenHint = idTokenHint;
                    }
                    return Task.FromResult(0);
                }
            }
     }
 }

帐户控制器具有注销操作

  public class AccountController:Controller
  {
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult LogOff()
    {
        Request.GetOwinContext().Authentication.SignOut();
        return Redirect("/");
    }
  }

ASP.NET核心

应用程序启动

    public static class IApplicationBuilderExtensions
    {
        public static void UseIdentityServer(this IApplicationBuilder app, string authority, string clientId)
        {
            app.UseCookieAuthentication(new CookieAuthenticationOptions()
            {
                AutomaticAuthenticate = true,
                AutomaticChallenge = true,
                AuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme,
                LoginPath = "/home",
                AccessDeniedPath = new PathString(IdentityConstant.AccessDeniedPath),
                CookieName = "MtAuthCookie",
                SlidingExpiration = true
            });

            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap = new Dictionary<string, string>();           

            var connectOptions = new OpenIdConnectOptions()
            {                
                AutomaticChallenge = true,
                Authority = authority,
                ClientId = clientId,
                ResponseType = "id_token",
                AuthenticationScheme = OpenIdConnectDefaults.AuthenticationScheme,
                SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme,             
                CallbackPath = "/home",
                Events = new OpenIdConnectEvents()
                {
                    OnTokenValidated = async context =>
                    {
                        //create new identity to store only required claims here.                       
                    },
                    OnRedirectToIdentityProvider = async context =>
                    {
                        if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
                        {
                            var idTokenHint = context.HttpContext.User.FindFirst("id_token");
                            if (idTokenHint != null)
                                context.ProtocolMessage.IdTokenHint = idTokenHint.Value;
                        }
                        await Task.FromResult(0);
                    }                    
                }
            };        


            app.UseOpenIdConnectAuthentication(connectOptions);
        }
    }
}

帐户控制器具有注销操作

  public class AccountController:Controller
  {
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> LogOff()
    {
        if (User.Identity.IsAuthenticated)
        {
            await HttpContext.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
        }
        return Redirect("/");
    }
  }

问题
在经典的asp.net注销操作中运行正常。我看到它会执行OnRedirectToIdentityProvider事件,并且context.ProtocolMessage.RequestType也设置为LogoutRequest,之后它会GET请求:

https://login.mydomain.com/identity/connect/endsession?id_token_hint=XXXXXXXXXXXXXX
https://login.mydomain.com/identity/logout?id=XXXXXX
https://login.mydomain.com/identity/connect/endsessioncallback?sid=XXXXXX

最后用户登陆https://devlogin.crowdreason.com/identity/logout?id=xxxx页面

但是在ASP.NET Core中https://login.mydomain.com/identity/connect/endsession永远不会在注销操作时被调用。我还注意到context.ProtocolMessage.RequestType永远不会被设置为Logout。 实际上在注销时用户会自动获得身份验证并返回主页?

另外

我在ASP.NET Core中缺少什么?使用IdentityServer3ASP.NET Core客户端是否有可用的示例? (注意我没有使用IdentityServer4)

1 个答案:

答案 0 :(得分:0)

我认为这是一个不同的事件。这对我有用:

OnRedirectToIdentityProviderForSignOut = context =>
                {
                    var idTokenHint = context.HttpContext.User.FindFirst("id_token");

                    if (idTokenHint != null)
                    {
                        context.ProtocolMessage.IdTokenHint = idTokenHint.Value;
                    }

                    return Task.FromResult(0);
                }