2017-06-21 263 views
2

我正在尝试获取IdentityServer4的隐式流。登录和注销工作正常,但是PostLogoutRedirectUri会返回null,尽管设置了需要设置的值。我希望注销过程在注销完成后重定向回我的应用程序。IdentityServer4 PostLogoutRedirectUri null

我正确地得到logoutId,并注销调用BuildLoggedOutViewModelAsync:

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

这种方法位于我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); 
... 

它创建一个IdentityServer4.Models.LogoutRequest。

SignOutIFrameUrl字符串属性设置为"http://localhost:5000/connect/endsession/callback?sid=bf112f7785bc860fcc4351893012622e&logoutId=d6649e7f818d9709b2c0bc659696abdf",但LogoutRequest中似乎没有填充任何其他内容。

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

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

这里是我的配置设置。

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客户端):

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(); 
    } 
} 

Startup.cs的相关部分:

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

搞清楚其中的任何援助我会错误的将不胜感激。

谢谢!

回答

0

尝试为MVC客户端配置LogoutUrl!

+0

喜@ JayDeeEss,我尝试添加LogoutUrl到IdentityServer,但没有运气。我没有MVC客户端,它是一个JavaScript客户端。我使用的是oidc-client.js文件,从我可以告诉的是没有logout_url属性。 – user2921364

+0

Hi @ user2921364!我创建了角度客户端(隐式流)与您的配置和它的工作正常。我唯一能想到的就是确保在服务下的AccountOptions.cs中将“AutomaticRedirectAfterSignout”选项设置为true。这是我的AccountOptions类的样子:(请查看上面的答案) – JayDeeEss

+2

嗨@JayDeeEss,感谢您对此的支持。事实证明,它不那么直观。我使用了新的Oidc.UserManager()。signRedirectCallback()。then ...'脚本,它位于index.html页面上。我决定按照'T'的指示并将其移至自己的callback.html页面。一旦我做到了,一切都开始奏效。最大的线索是'userManager.getUser()'总是返回null,即使登录了。我意识到登录过程中缺少一些东西。 – user2921364

0

请确保您有这些设置正确配置:

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"; 
     } 
2

通id_token_hint ARG到signoutRedirect()

你可以从signinRedirect返回的用户对象id_token_hint();

因此可以说你的ts文件中有一个名为“user”的变量,该变量是通过用户通过signinRedirect()登录而设置的。

,那么你会怎么做?

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