登录后重定向到原始URL

时间:2019-08-02 23:10:52

标签: angular angular7 identityserver4 openid-connect oidc-client-js

我将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>();

身份服务器资源,Api资源和客户端

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

    }

  };

}

Api配置

  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 Auth Service

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

}

1 个答案:

答案 0 :(得分:0)

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

作为创建授权URL的一种选择,您可以在后端存储有关原始URL的信息,并添加带有此信息ID的状态。收到回调后,您可以从state中读取ID,然后返回到客户端以对其进行重定向。

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

我使用openid-client,所以我不喜欢oidc-client.js。 stateRFC 6749中所述的此类情况的标准参数-必须以某种方式存在。

相关问题