0

我将 Identity Server 4 与 ASP.NET core 2.2、Angular 7 和OICD-Client.js 一起使用

在客户端应用程序上,我在尝试访问受保护的路由后被重定向到登录,例如:

/protected-route

登录后,我被重定向到 Angular SPA 应用程序的回调:

/auth-callback

在 auth-callback 路由中,我完成了登录:

export class AuthCallbackComponent implements OnInit {

  constructor(private authService: AuthService) { }

  ngOnInit() {

    this.authService.signinRedirectCallback();

  }

}

我怎样才能获得原始路线,例如,/protected-route并重定向到它?

如果有必要回答我留下我的配置:

身份服务器配置

  services
    .AddIdentity<Use, Roler>(x => {
      x.User.RequireUniqueEmail = true;
    })
    .AddEntityFrameworkStores<Context>()
    .AddDefaultTokenProviders();

  services.Configure<IISOptions>(x => {
    x.AuthenticationDisplayName = "Windows";
    x.AutomaticAuthentication = false;
  });

  services
    .AddIdentityServer(x => {
      x.Events.RaiseErrorEvents = true;
      x.Events.RaiseInformationEvents = true;
      x.Events.RaiseFailureEvents = true;
      x.Events.RaiseSuccessEvents = true;
      x.UserInteraction.LoginUrl = "/login";
      x.UserInteraction.LogoutUrl = "/logout";
    })
    .AddDeveloperSigningCredential()
    .AddInMemoryIdentityResources(Config.Resources())
    .AddInMemoryApiResources(Config.ApiResources())
    .AddInMemoryClients(Config.Clients())
    .AddAspNetIdentity<User>();

身份服务器资源、ApiResources 和客户端

public static List<ApiResource> ApiResources() {

  return new List<ApiResource> { 

    new ApiResource {
      Name = "api",
      DisplayName = "API Resource",
      ApiSecrets = { new Secret("Secret".Sha256()) },
      UserClaims = { JwtClaimTypes.Name, JwtClaimTypes.Email },
      Scopes = {
        new Scope { Name = "api", DisplayName = "API Recource" }
      }
    }

  };

} 

public static List<IdentityResource> IdentityResources() {

  return new List<IdentityResource> { 
    new IdentityResources.OpenId(),
    new IdentityResources.Profile(),
    new IdentityResources.Email()  
  };

}  

public static List<Client> Clients() {

  return new List<Client> { 

    new Client {

      ClientId = "spa",
      ClientName = "SPA Client",

      ClientSecrets = { new Secret("Secret".Sha256()) },
      RequireClientSecret = false,

      AllowedGrantTypes = GrantTypes.Code,
      RequirePkce = true,

      AllowAccessTokensViaBrowser = true,
      AllowOfflineAccess = true,
      RequireConsent = true,

      AllowedScopes = { 
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile, 
        IdentityServerConstants.StandardScopes.Email, 
        IdentityServerConstants.StandardScopes.OfflineAccess,
        "api" 
      },  

      RedirectUris = new List<String> { 
        "https://localhost:5001/auth-callback"
      },

      PostLogoutRedirectUris = new List<String> { 
        "https://localhost:5000" 
      }

    }

  };

}

接口配置

  services.AddCors(x => {
      x.AddPolicy("AllowAll", y => y.AllowAnyMethod().AllowAnyOrigin().AllowAnyHeader());
    }); 

  services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
    .AddIdentityServerAuthentication(x => {
      x.ApiName = "api";
      x.ApiSecret = "Secret";
      x.Authority = "https://localhost:5005";
      x.RequireHttpsMetadata = false;
    });

Angular SPA 身份验证服务

import { Injectable } from '@angular/core';

import { UserManager, UserManagerSettings, User } from 'oidc-client';

const settings : UserManagerSettings = {
  authority: 'https://localhost:5005',
  client_id: 'spa',
  redirect_uri: 'https://localhost:5001/auth-callback',
  post_logout_redirect_uri: 'https://localhost:5001',
  response_type: "code",
  scope: 'openid profile email offline_access api',
  filterProtocolClaims: true,
  loadUserInfo: true
};

@Injectable({ 
  providedIn: 'root' 
})

export class AuthService {

  private manager = new UserManager(settings);
  private user: User = null;

  constructor() {

    this.manager.getUser().then(user => {
      this.user = user;
    });

  }

  isSignedin(): boolean {
    return this.user != null && !this.user.expired;
  }

  getClaims(): any {
    return this.user.profile;
  }

  getAuthorizationHeaderValue(): string {
    return `${this.user.token_type} ${this.user.access_token}`;
  }

  signinRedirect(): Promise<void> {
    return this.manager.signinRedirect();
  }

  signinRedirectCallback(): Promise<void> {
    return this.manager.signinRedirectCallback().then(user => {
      this.user = user;
    });
  }

}
4

1 回答 1

1

在 OAuth2 流程中,当您创建授权服务器的 URL 时,您可以添加state参数。用户成功登录后,服务器将重定向到指定的重定向 URL 并添加codestate作为查询参数。

作为创建授权 URL 时的一个选项,您可以在后端存储有关原始 URL 的信息,并使用此信息的 ID 添加状态。当您收到回调时,您可以从中读取 IDstate并将其返回给您的客户端重定向自身的位置。

或者您可以简单地将原始 URL 存储在状态中。))

我使用openid-client,所以我不知道如何使用 oidc-client.js。是RFC 6749state中描述的这种情况的标准化参数- 它必须以某种方式存在。

于 2020-07-09T11:04:03.750 回答