如何在identityserver3中使用ajax注销用户

时间:2018-02-07 09:07:23

标签: c# ajax asp.net-mvc identity identityserver3

我将我的身份服务器项目设置为跳过注销页面。它显示注销页面一两秒。但我设置PostSignOutAutoRedirectDelay = 0所以我想要注销用户ajax.But我得到:预检的响应有无效的HTTP状态代码405 。 我的日志文件说:

2018-02-07 11:49:40.475 +03:30 [Information] End authorize request
2018-02-07 11:49:40.479 +03:30 [Information] Posting to 
http://localhost:14600/
2018-02-07 11:49:40.480 +03:30 [Debug] Using DefaultViewService to render 
authorization response HTML
2018-02-07 11:49:57.949 +03:30 [Information] CORS request made for path: 
"/connect/endsession" from origin: "http://localhost:14600" but rejected 
because invalid CORS path

这是我的客户端类代码:

我的创业班:

    public void Configuration(IAppBuilder app)
    {

        app.Map("/identity", idsrvApp =>
        {
            var factory =
                new IdentityServerServiceFactory().UseInMemoryClients(Clients.Get())
                                                  .UseInMemoryScopes(Scopes.Get())
                                                  .UseInMemoryUsers(Users.Get());

            var userService = new UserService();


            factory.UserService = new Registration<IUserService>(reslove => userService);
            var viewOptions = new DefaultViewServiceOptions();
            viewOptions.CacheViews = false;
            factory.ConfigureDefaultViewService(viewOptions);
            var options = new IdentityServerOptions
            {
                SigningCertificate = LoadCertificate(),

                Factory = factory,
                Endpoints = new EndpointOptions()
                {
                    EnableCspReportEndpoint = true,
                    EnableAuthorizeEndpoint = true,
                    EnableTokenRevocationEndpoint = true,
                    EnableEndSessionEndpoint = true,
                    EnableCheckSessionEndpoint = true,
                    EnableUserInfoEndpoint = true,
                    EnableDiscoveryEndpoint = true,
                    EnableTokenEndpoint = true,
                    EnableIdentityTokenValidationEndpoint = true,
                    EnableClientPermissionsEndpoint = true,
                    EnableAccessTokenValidationEndpoint = true,
                    EnableIntrospectionEndpoint = true
                },
                AuthenticationOptions = new IdentityServer3.Core.Configuration.AuthenticationOptions
                {
                    //sign out with out confirm
                    EnablePostSignOutAutoRedirect = true,
                    EnableSignOutPrompt = false,
                    PostSignOutAutoRedirectDelay=0


                    //   IdentityProviders = ConfigureAdditionalIdentityProviders,
                }
            };

            idsrvApp.UseIdentityServer(options);
        });

        string ss = HttpContext.Current.Server.MapPath("~/Content/identity.log");
        Serilog.Log.Logger =
            new LoggerConfiguration().MinimumLevel.Debug()
                .WriteTo.RollingFile(pathFormat: ss)
                .CreateLogger();
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = "Cookies"
        });


        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            Authority = ConfigurationManager.AppSettings["Authority"],

            ClientId = "Identity",
            Scope = "openid profile roles sampleApi",
            ResponseType = "id_token token",
            RedirectUri = ConfigurationManager.AppSettings["RedirectUri"],

            SignInAsAuthenticationType = "Cookies",
            UseTokenLifetime = false,
            PostLogoutRedirectUri= "https://www.google.com",
            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                SecurityTokenValidated = async n =>
                {
                    var nid = new ClaimsIdentity(
                        n.AuthenticationTicket.Identity.AuthenticationType,
                        Constants.ClaimTypes.GivenName,
                        Constants.ClaimTypes.Role);
                    // get userinfo data
                    var userInfoClient = new UserInfoClient(
                        new Uri(n.Options.Authority + "/connect/userinfo"),
                        n.ProtocolMessage.AccessToken);

                    var userInfo = await userInfoClient.GetAsync();
                    userInfo.Claims.ToList().ForEach(ui => nid.AddClaim(new Claim(ui.Item1, ui.Item2)));

                    // keep the id_token for logout
                    nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));

                    // add access token for sample API
                    nid.AddClaim(new Claim("access_token", n.ProtocolMessage.AccessToken));

                    // keep track of access token expiration
                    nid.AddClaim(new Claim("expires_at", DateTimeOffset.Now.AddSeconds(int.Parse(n.ProtocolMessage.ExpiresIn)).ToString()));

                    // add some other app specific claim
                    nid.AddClaim(new Claim("app_specific", "some data"));

                    n.AuthenticationTicket = new AuthenticationTicket(
                        nid,
                        n.AuthenticationTicket.Properties);
                },

                RedirectToIdentityProvider = n =>
                {
                    if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
                    {
                        var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");

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

                    return Task.FromResult(0);
                }
            }
        });
    }

我的行动:

public ActionResult Logout()
    {
        Request.GetOwinContext().Authentication.SignOut();
        return Redirect("/");
    }

1 个答案:

答案 0 :(得分:0)

IdentityServer 3(和4)是OpenID Connect及其当前实施者草案的某些扩展的实现。 在OpenID Connect中,无法通过ajax发出注销请求。您有两种注销方法……假设您使用的是前渠道(用户代理):

  • 清除您的应用程序会话,这将使用户退出当前应用程序(RP),而不是openid提供程序
  • 发出结束会话端点的请求,并让您的应用程序在预先配置的注销URL上侦听注销注销请求,以清除本地会话。这将使您退出所有应用程序