简体   繁体   English

IdentityServer4 PostLogoutRedirectUri null

[英]IdentityServer4 PostLogoutRedirectUri null

I am attempting to get the implicit flow working for IdentityServer4.我正在尝试让隐式流程为 IdentityServer4 工作。 Login and logout work correctly, however the PostLogoutRedirectUri is coming back null, despite setting the value where it needs to be set.登录和注销工作正常,但是 PostLogoutRedirectUri 返回 null,尽管在需要设置的地方设置了值。 What I would like is for the logout process to redirect back to my application after the logout is complete.我想要的是注销过程在注销完成后重定向回我的应用程序。

I am getting the logoutId correctly, and Logout calls BuildLoggedOutViewModelAsync:我正在正确获取 logoutId,注销调用 BuildLoggedOutViewModelAsync:

[HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Logout(LogoutInputModel model)
    {
        var vm = await _account.BuildLoggedOutViewModelAsync(model.LogoutId);
...

This method is located in my AccountService.cs class, which then calls the GetLogoutContextAsync of the DefaultIdentityServiceInteractionService:这个方法位于我的AccountService.cs class,然后调用DefaultIdentityServiceInteractionService的GetLogoutContextAsync:

public async Task<LoggedOutViewModel> BuildLoggedOutViewModelAsync(string logoutId)
    {
        // get context information (client name, post logout redirect URI and iframe for federated signout)
        var logout = await _interaction.GetLogoutContextAsync(logoutId);
...

Which creates a IdentityServer4.Models.LogoutRequest.这会创建一个 IdentityServer4.Models.LogoutRequest。

The SignOutIFrameUrl string property is set to "http://localhost:5000/connect/endsession/callback?sid=bf112f7785bc860fcc4351893012622e&logoutId=d6649e7f818d9709b2c0bc659696abdf" but nothing else seems to have been populated in the LogoutRequest. SignOutIFrameUrl字符串属性设置为"http://localhost:5000/connect/endsession/callback?sid=bf112f7785bc860fcc4351893012622e&logoutId=d6649e7f818d9709b2c0bc659696abdf" ,但 LogoutRequest 中似乎没有填充任何其他内容。

Unfortunately, this means that the PostLogoutRedirectUri is null and the AutomaticRedirectAfterSignOut is also null, and when the LoggedOut.cshtml page is loaded, the signout-callback.js file is never loaded:不幸的是,这意味着PostLogoutRedirectUri是 null,而AutomaticRedirectAfterSignOut也是 null,当加载LoggedOut.cshtml页面时,永远不会加载signout-callback.js文件:

@section scripts
{
    @if (Model.AutomaticRedirectAfterSignOut)
    {
        <script src="~/js/signout-redirect.js"></script>
    }
}

Here are my configuration settings.这是我的配置设置。

Config.cs:配置文件:

public static IEnumerable<Client> GetClients()
    {
        return new List<Client>
        {
            new Client
            {
                ClientId = "implicit.client",
                AllowedGrantTypes = GrantTypes.Implicit,
                AllowAccessTokensViaBrowser = true,
                AllowedScopes = 
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    "ContractManagerAPI"
                },
                RedirectUris = { "http://localhost:9000/" },
                PostLogoutRedirectUris = { "http://localhost:9000/" },
                AllowedCorsOrigins = { "http://localhost:9000" },
                RequireConsent = false,

            }                
        };
    }

app.ts (js client): app.ts(js 客户端):

import {UserManager} from 'oidc-client';
import { inject, Factory } from 'aurelia-framework';

@inject(Factory.of(UserManager))
export class App {
  userManager: UserManager;

  constructor(userManagerFactory){
    let config = {
      authority: 'http://localhost:5000',
      client_id: 'implicit.client',
      response_type: 'id_token token',
      scope: 'openid profile ContractManagerAPI',
      redirect_uri: 'http://localhost:9000/',
      post_logout_redirect_uri: 'http://localhost:9000/'
    };

    this.userManager = userManagerFactory(config);
  }

  login(){
    this.userManager.signinRedirect();
  }

  logout(){
    this.userManager.signoutRedirect();
  }
}

Relevant parts of Startup.cs: Startup.cs 的相关部分:

services.AddIdentityServer()
                .AddTemporarySigningCredential()
                .AddInMemoryApiResources(Config.GetApiResources())
                .AddInMemoryClients(Config.GetClients())
                .AddInMemoryIdentityResources(Config.GetIdentityResources())
                .AddContractManagerUserStore()
                .AddProfileService<ContractManagerProfileService>();

Any assistance in figuring out where I'm going wrong would be greatly appreciated.任何帮助找出我哪里出错的帮助将不胜感激。

Thanks!谢谢!

pass id_token_hint arg to signoutRedirect()将 id_token_hint 参数传递给 signoutRedirect()

you can get id_token_hint from the User object returned by signinRedirect();您可以从 signinRedirect() 返回的 User 对象中获取 id_token_hint;

so lets say you got a variable called "user" in your ts file that got set as a result of the user logging in via signinRedirect().因此,假设您在 ts 文件中有一个名为“user”的变量,该变量是由于用户通过 signinRedirect() 登录而设置的。

then you would do...那么你会做...

logout(){
    this.userManager.signoutRedirect({ 'id_token_hint': this.user.id_token });
}

I was running into (possibly) the same issue as the OP.我遇到了(可能)与 OP 相同的问题。

After examining the logs from IdentityServer, I noticed that an exception was being thrown just after the request information containing my client information was sent to the IdentityServer server.在检查了 IdentityServer 的日志后,我注意到在将包含我的客户端信息的请求信息发送到 IdentityServer 服务器之后,抛出了一个异常。

This lead me to this github post which addresses the error directly.这让我找到了这个 github 帖子,它直接解决了错误。 The solution was to update to IdentityServer4 v4.1.2.解决方案是更新到 IdentityServer4 v4.1.2。 I then re-ran my code and voila!然后我重新运行我的代码,瞧! the PostLogoutRedirectUri (and other parameters) were now correctly populated from the var context = await _interaction.GetLogoutContextAsync(logoutId); PostLogoutRedirectUri(和其他参数)现在从var context = await _interaction.GetLogoutContextAsync(logoutId);正确填充var context = await _interaction.GetLogoutContextAsync(logoutId); call.打电话。

Make sure you have these settings properly configured:确保您正确配置了这些设置:

public class AccountOptions
        {
            public static bool AllowLocalLogin = true;
            public static bool AllowRememberLogin = true;
            public static TimeSpan RememberMeLoginDuration = TimeSpan.FromDays(30);

            public static bool ShowLogoutPrompt = false;
            public static bool AutomaticRedirectAfterSignOut = true;

            public static bool WindowsAuthenticationEnabled = false;
            // specify the Windows authentication schemes you want to use for authentication
            public static readonly string[] WindowsAuthenticationSchemes = new string[] { "Negotiate", "NTLM" };
            public static readonly string WindowsAuthenticationDisplayName = "Windows";

            public static string InvalidCredentialsErrorMessage = "Invalid username or password";
        }

I want to share my experience of solving issues with null PostLogoutRedirectUri value.我想分享我解决空 PostLogoutRedirectUri 值问题的经验。

To initiate Logout process you must first call SignOut("Cookies", "oidc") on mvc client side.要启动注销过程,您必须首先在 mvc 客户端调用SignOut("Cookies", "oidc") Otherwise you will have null logoutId value on Identity Server side.否则,您将在 Identity Server 端获得 null logoutId 值。 Example endpoint in my HomeController:我的 HomeController 中的示例端点:

public IActionResult Logout()
{
    return SignOut("Cookies", "oidc");
}

I always had null PostLogoutRedirectUri value in logout context until I added SignInScheme value on mvc client side.我在注销上下文中总是有空 PostLogoutRedirectUri 值,直到我在 mvc 客户端添加SignInScheme值。 These settings of authentication on MVC client side works for me: MVC 客户端的这些身份验证设置对我有用:

var authenticationBuilder = services.AddAuthentication(options =>
{
    options.DefaultScheme = "Cookies";
    options.DefaultChallengeScheme = "oidc";
});

authenticationBuilder.AddCookie(options =>
{
    options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
    options.Cookie.Name = "identity_server_mvc";
});

authenticationBuilder.AddOpenIdConnect("oidc", options =>
{
    options.Authority = "{IDENTITY_SERVER_URL}";
    options.ClientId = "mvc";
    options.SaveTokens = true;
    options.SignInScheme = "Cookies";
});

You also need to make sure that you have added the PostLogoutRedirectUri value to the client configuration on the Identity Server side:您还需要确保已将 PostLogoutRedirectUri 值添加到 Identity Server 端的客户端配置中:

new Client
{
    ClientId = "mvc",
    AllowedGrantTypes = GrantTypes.Implicit,

    RedirectUris           = { "{CLIENT_URL}/signin-oidc" },
    PostLogoutRedirectUris = { "{CLIENT_URL}/signout-callback-oidc" },

    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile
    }
}

Hope it helps!希望有帮助!

尝试为 MVC 客户端配置 LogoutUrl!

对我来说,解决 null 的是在 mvc 客户端上设置的波纹管选项

o.SignedOutCallbackPath = new PathString("/signout-callback-oidc");

GetLogoutContextAsync returns also a null-PostLogoutRedirectUri when the configured URI in Config.cs does not match with the configured URI of the JS-Client.Config.cs中配置的 URI 与 JS-Client 的配置 URI 不匹配时, GetLogoutContextAsync 也会返回 null-PostLogoutRedirectUri。

If you are using EF core based configuration you need to verify the URI in the ClientPostLogoutRedirectUris table.如果您使用的是基于 EF 核心的配置,则需要验证ClientPostLogoutRedirectUris表中的 URI。

Does't seem to apply to your problem though.虽然似乎不适用于您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM