IdentityServer4 PostLogoutRedirectUri为null

use*_*364 4 c# implicit identityserver4 oidc-client-js

我试图让隐式流程为IdentityServer4工作.登录和注销正常工作,但PostLogoutRedirectUri返回null,尽管设置了需要设置的值.我想要的是注销过程在注销完成后重定向回我的应用程序.

我正确获取logoutId,Logout调用BuildLoggedOutViewModelAsync:

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

此方法位于我的AccountService.cs类中,然后调用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);
...
Run Code Online (Sandbox Code Playgroud)

这会创建一个IdentityServer4.Models.LogoutRequest.

SignOutIFrameUrl字符串属性设置为"http://localhost:5000/connect/endsession/callback?sid=bf112f7785bc860fcc4351893012622e&logoutId=d6649e7f818d9709b2c0bc659696abdf",但没有别的似乎都在LogoutRequest被填充.

不幸的是,这意味着它PostLogoutRedirectUri是null并且AutomaticRedirectAfterSignOut也是null,并且当LoggedOut.cshtml加载页面时,signout-callback.js永远不会加载该文件:

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

这是我的配置设置.

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,

            }                
        };
    }
Run Code Online (Sandbox Code Playgroud)

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();
  }
}
Run Code Online (Sandbox Code Playgroud)

Startup.cs的相关部分:

services.AddIdentityServer()
                .AddTemporarySigningCredential()
                .AddInMemoryApiResources(Config.GetApiResources())
                .AddInMemoryClients(Config.GetClients())
                .AddInMemoryIdentityResources(Config.GetIdentityResources())
                .AddContractManagerUserStore()
                .AddProfileService<ContractManagerProfileService>();
Run Code Online (Sandbox Code Playgroud)

任何协助找出我出错的地方将不胜感激.

谢谢!

小智 5

将id_token_hint arg传递给signoutRedirect()

你可以从signinRedirect()返回的User对象中获取id_token_hint;

所以假设你的ts文件中有一个名为"user"的变量,由于用户通过signinRedirect()登录而设置了该变量.

那你会做...

logout(){
    this.userManager.signoutRedirect({ 'id_token_hint': this.user.id_token });
}
Run Code Online (Sandbox Code Playgroud)

  • 另外,请确保您实际上发送的是身份令牌,而不是 id_token_hint 的访问令牌。我为此苦苦挣扎,因为我没有收到任何错误告诉我发送了错误的令牌,它就是行不通。 (2认同)

Jay*_*Ess 0

尝试为 MVC 客户端配置 LogoutUrl!

  • 您好@JayDeeEss,感谢您对此的投入。事实证明它不太直观。我的“new Oidc.UserManager().signRedirectCallback().then...”脚本位于index.html 页面上。我决定按照“T”的说明进行操作,并将其移动到它自己的callback.html 页面。一旦我这样做了,一切就开始起作用了。最大的线索是“userManager.getUser()”总是返回 null,即使在登录时也是如此。我意识到登录过程中缺少一些东西。 (2认同)