Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
重定向到Angular应用程序后缺少声明_Angular_Identityserver4_Openid Connect - Fatal编程技术网

重定向到Angular应用程序后缺少声明

重定向到Angular应用程序后缺少声明,angular,identityserver4,openid-connect,Angular,Identityserver4,Openid Connect,我们已经设置了一个身份服务器,用于所有身份验证和授权。我们一直在网上关注大多数例子,但也许我们遗漏了一些东西 我正在分享下面的所有内容,但是如果你需要看其他东西,尽管问 预期流量/性能: 用户转到Web应用程序(角度) Web应用程序确定用户是否经过身份验证,如果没有,则重定向到身份验证服务器 身份验证服务器执行它所执行的操作,用户最终进入登录页面 用户登录 如果登录成功,身份验证服务将登录用户并分配身份声明 身份验证服务器重定向回Web应用 Web应用程序应该能够在令牌中查看声明,特别是查找组

我们已经设置了一个身份服务器,用于所有身份验证和授权。我们一直在网上关注大多数例子,但也许我们遗漏了一些东西

我正在分享下面的所有内容,但是如果你需要看其他东西,尽管问

预期流量/性能:

  • 用户转到Web应用程序(角度)
  • Web应用程序确定用户是否经过身份验证,如果没有,则重定向到身份验证服务器
  • 身份验证服务器执行它所执行的操作,用户最终进入登录页面
  • 用户登录
  • 如果登录成功,身份验证服务将登录用户并分配身份声明
  • 身份验证服务器重定向回Web应用
  • Web应用程序应该能够在令牌中查看声明,特别是查找
    组织\u id
    组织\u short\u name
  • 实际流量/行为: 1.用户转到Web应用程序(角度) 2.Web应用程序确定用户是否经过身份验证,如果没有,则重定向到身份验证服务器 3.身份验证服务器执行它所执行的操作,用户最终进入登录页面 4.用户登录 5.如果登录成功,身份验证服务将登录用户并分配身份声明。(已核实) 6.身份验证服务器重定向回Web应用 7.Web应用程序只能查看标准声明(请参见下文)

    由于我总是将cludeuserclaimsindtoken设置为true,我希望所有用户声明都会出现

    我还想指出,我确实将response\u type设置为
    id\u-token-token
    ,但结果与现在的
    id\u-token
    相同。返回提供了访问(承载)令牌

    返回的索赔

    {"sid":"a994edfc711e0729e133acbcc9cde367","sub":"6f1803fc-125e-4920-557d-08d695d06a94","auth_time":1551446274,"idp":"local","username":"me@example.com","role":"Support","amr":["pwd"]}
    
    [ValidateAntiForgeryToken]
    [HttpPost("login", Name = nameof(PostLogin))]
    public async Task<IActionResult> PostLogin(LoginViewModel model)
    {
        if (ModelState.IsValid)
        {
            var user = await _memberManager.FindByEmailAsync(model.UserName);
    
            if (user != null && !await _memberManager.IsLockedOutAsync(user))
            {
                if (await _memberManager.CheckPasswordAsync(user, model.Password))
                {
                    if (!await _memberManager.IsEmailConfirmedAsync(user))
                    {
                        await _memberManager.ResetAccessFailedCountAsync(user);
    
                        if (await _memberManager.GetTwoFactorEnabledAsync(user))
                        {
                            _logger.LogInformation(
                                "Login attempt for `{username}` successful but has 2FA/2SA Enabled.",
                                user.UserName);
                            var validProviders = await _memberManager.GetValidTwoFactorProvidersAsync(user);
                            if (validProviders.Contains(_memberManager.Options.Tokens.AuthenticatorTokenProvider))
                            {
                                //await HttpContext.SignInAsync(IdentityConstants.TwoFactorUserIdScheme)
                            }
                        }
    
    
                        if (user.Organizations.Count == 0)
                        {
                            // TODO : Build Page to inform member they have not associated organizations
                        }
                        else if (user.Organizations.Count > 1)
                        {
                            // TODO : Build Page to let member select organization they want to login into
                        }
    
                        _claimsPrincipalFactory.Organization = user.Organizations.FirstOrDefault()?.Organization;
    
                        await HttpContext.SignOutAsync();
                        await HttpContext.SignOutAsync(IdentityConstants.ApplicationScheme);
                        await HttpContext.SignOutAsync(IdentityServerConstants.DefaultCookieAuthenticationScheme);
    
                        var principal = await _claimsPrincipalFactory.CreateAsync(user);
                        await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, principal);
    
                        //var result = await _signInManager.PasswordSignInAsync(model.UserName, model.Password,
                        //    model.RememberMe, true);
    
                        await _memberManager.RecordLoginAttempt(user.Id, LoginStatusType.Success);
                        _logger.LogInformation("Login attempt for `{username}` successful.", user.UserName);
                        if (string.IsNullOrWhiteSpace(model.ReturnUrl)) return View("UserClaims");
                        return Redirect(model.ReturnUrl);
                    }
    
                    await _memberManager.RecordLoginAttempt(user.Id, LoginStatusType.Failure);
                    _logger.LogInformation("Login attempt for `{username}` but email is unconfirmed.",
                        user.UserName);
                    ModelState.AddModelError("", _localizer["UnconfirmedEmail"]);
                }
                else
                {
                    await _memberManager.RecordLoginAttempt(user.Id, LoginStatusType.Failure);
                    await _memberManager.AccessFailedAsync(user);
    
                    if (await _memberManager.IsLockedOutAsync(user))
                        _logger.LogInformation(
                            "Login attempt for `{username}` but account is locked out until {lockout}",
                            user.UserName, user.LockoutEnd);
                }
            }
            else
            {
                _logger.LogWarning("Login attempt for unknown username: {username}", model.UserName);
                ModelState.AddModelError("", _localizer["InvalidUsernameOrPassword"]);
            }
        }
    
        return View("Login", model);
    }
    
    public class MemberClaimsPrincipalFactory : UserClaimsPrincipalFactory<Member>
        {
            private readonly MemberManager _memberManager;
            private readonly OrganizationRoleManager _organizationRoleManager;
    
            public MemberClaimsPrincipalFactory(MemberManager userManager,
                OrganizationRoleManager organizationRoleManager,
                IOptions<IdentityOptions> optionsAccessor)
                : base(userManager, optionsAccessor)
            {
                _memberManager = userManager;
                _organizationRoleManager = organizationRoleManager;
            }
    
            public Organization Organization { get; set; }
    
            #region Overrides of UserClaimsPrincipalFactory<Member>
    
            public async Task<ClaimsPrincipal> CreateAsync(Member user)
            {
                if (user == null) throw new ArgumentNullException(nameof(user));
                var id = await GenerateClaimsAsync(user);
                return new ClaimsPrincipal(id);
            }
    
            #endregion
    
            protected async Task<ClaimsIdentity> GenerateClaimsAsync(Member user)
            {
                if (Organization == null) throw new NullReferenceException("Organization must have value.");
    
                var identity = await base.GenerateClaimsAsync(user);
    
                // Add Organization Details
                identity.AddClaim(new Claim("organization_id", Organization.Id.ToString()));
                identity.AddClaim(new Claim("organization_short_name", Organization.ShortName));
    
                // Add Username
                identity.AddClaim(new Claim("username", user.UserName));
    
                // Adding Role(s) and Role Claim(s)
                var roleIds = await _memberManager.GetOrganizationRoleIds(user);
                foreach (var roleId in roleIds)
                {
                    var orgRole = await _organizationRoleManager.GetRoleById(Organization.Id, roleId);
                    identity.AddClaim(new Claim("role", orgRole.Name));
                    var roleClaims = await _organizationRoleManager.GetClaimsByRoleId(orgRole.Id);
                    identity.AddClaims(roleClaims);
                }
    
    
                // Adding Member Claim(s)
                var claims = await _memberManager.GetClaimsAsync(user);
                foreach (var claim in claims)
                    identity.AddClaim(new Claim(claim.Type.ToLower(), claim.Value));
    
    
                return identity;
            }
        }
    
    import { Injectable } from '@angular/core';
    
    import { UserManager, UserManagerSettings, User } from 'oidc-client';
    import { fail } from 'assert';
    
    import { environment } from '../environments/environment';
    import { UserProfile } from '../models/userprofile';
    
    @Injectable()
    export class AuthService {
      private manager: UserManager = new UserManager(getClientSettings());
      private user: User = null;
    
      constructor() {
        this.manager.getUser().then(user => {
          this.user = user;
        });
    
        //console.log("auth.service.constructor.user=" + this.user);
        //https://github.com/IdentityModel/oidc-client-js/wiki
    
        //EVENTS - begin
        this.manager.events.addSilentRenewError(function (e) {
          console.log("silent renew error", e.message);
        });
    
        this.manager.events.addAccessTokenExpired(function () {
          if (environment.debug_mode) {
            console.log("token has expired...");
          }
          //creates a loop
          //window.location.href = "/logoff/";
        });
    
        this.manager.events.addUserLoaded(function () {
          if (environment.debug_mode) {
            console.log("user has been loaded, redirect to cases...");
          }
    
          window.location.href = "/cases/";
        });
        //EVENTS - end
    
    
      }
    
      isLoggedIn(): boolean {
        return this.user != null && !this.user.expired;
      }
    
      getUser(): any {
        return this.user;
      }
    
      isUserExpired(): boolean {
        if (this.user != null)
          return this.user.expired
        else
          return true;
      }
    
      getAccessToken(): string {
        return this.user.access_token;
      }
    
      getTokenType(): string {
        return this.user.token_type;
      }
    
      getClaims(): any {
        return this.user.profile;
      }
    
      getScopes(): any {
        return this.user.scopes;
      }
    
      startAuthentication(): Promise<void> {
        return this.manager.signinRedirect();
      }
    
      completeAuthentication(): Promise<void> {
        return this.manager.signinRedirectCallback().then(user => {
          this.user = user;
        });
      }
    
      hasPermission(permission: string, category: string, subcategory: string): boolean {
    
        let rtn: boolean = false;
    
        if (this.user != null) {
    
          let userProfile: UserProfile = this.getClaims();
    
          let claim: string = category + "__" + subcategory;
    
          let profile: string = userProfile[claim];
    
          if (profile == undefined) {
            return false;
          }
    
          if (environment.debug_mode) {
            //console.log("hasPermission, profile: " + profile);
          }
    
          if (profile.includes(permission)) {
            rtn = true;
          }
        }
    
        return rtn;
      }
    
      logout(): Promise<void> {
    
        return this.manager.signoutRedirect();
    
      }
    }
    
    export function getClientSettings(): UserManagerSettings {
      return {
        authority: environment.auth_authority,
        client_id: environment.auth_client_id,
        redirect_uri: environment.auth_redirect_uri,
        post_logout_redirect_uri: environment.auth_post_logout_redirect_uri,
        response_type: "id_token",
        scope: environment.auth_scope,
        filterProtocolClaims: true,
        loadUserInfo: true
        //metadata: {
        //  issuer: environment.auth_authority.substring(0, environment.auth_authority.length - 1),
        //  jwks_uri: environment.auth_authority + '.well-known/openid-configuration/jwks',
        //  end_session_endpoint: environment.auth_authority + 'connect/endsession',
        //  authorization_endpoint: environment.auth_authority + 'connect/authorize',
        //  userinfo_endpoint: environment.auth_authority + 'connect/userinfo'
        //}
        //automaticSilentRenew: true,
        //silent_redirect_uri: 'http://localhost:4200/silent-refresh.html'
      };
    }
    
    export const environment = {
      production: false,
      debug_mode: true,
      version: "{VERSION}",
      auth_authority: (<any>window)._env.auth_authority,
      auth_redirect_uri: (<any>window)._env.auth_redirect_uri,
      auth_post_logout_redirect_uri: (<any>window)._env.auth_post_logout_redirect_uri,
      auth_client_id: "ui-web-app",
      auth_scope: "openid organization",
    
      //APIs.
      oc_api_members_url: "api/members/",
      oc_api_appointments_url: "api/appointments/",
      oc_api_centers_url: "api/centers/",
      oc_api_organizations_url: "api/organizations/",
      oc_api_procedure_protocols_url: "api/procedureprotocols/",
      auth_api_organizations_url: "api/organizations/"
    
    };
    
    window._env = {
        auth_authority: 'http://localhost:5000/',
        auth_redirect_uri: "http://localhost:4200/auth-callback",
        auth_post_logout_redirect_uri: "http://localhost:4200/",
       };
    
    AccountsController.cs

    {"sid":"a994edfc711e0729e133acbcc9cde367","sub":"6f1803fc-125e-4920-557d-08d695d06a94","auth_time":1551446274,"idp":"local","username":"me@example.com","role":"Support","amr":["pwd"]}
    
    [ValidateAntiForgeryToken]
    [HttpPost("login", Name = nameof(PostLogin))]
    public async Task<IActionResult> PostLogin(LoginViewModel model)
    {
        if (ModelState.IsValid)
        {
            var user = await _memberManager.FindByEmailAsync(model.UserName);
    
            if (user != null && !await _memberManager.IsLockedOutAsync(user))
            {
                if (await _memberManager.CheckPasswordAsync(user, model.Password))
                {
                    if (!await _memberManager.IsEmailConfirmedAsync(user))
                    {
                        await _memberManager.ResetAccessFailedCountAsync(user);
    
                        if (await _memberManager.GetTwoFactorEnabledAsync(user))
                        {
                            _logger.LogInformation(
                                "Login attempt for `{username}` successful but has 2FA/2SA Enabled.",
                                user.UserName);
                            var validProviders = await _memberManager.GetValidTwoFactorProvidersAsync(user);
                            if (validProviders.Contains(_memberManager.Options.Tokens.AuthenticatorTokenProvider))
                            {
                                //await HttpContext.SignInAsync(IdentityConstants.TwoFactorUserIdScheme)
                            }
                        }
    
    
                        if (user.Organizations.Count == 0)
                        {
                            // TODO : Build Page to inform member they have not associated organizations
                        }
                        else if (user.Organizations.Count > 1)
                        {
                            // TODO : Build Page to let member select organization they want to login into
                        }
    
                        _claimsPrincipalFactory.Organization = user.Organizations.FirstOrDefault()?.Organization;
    
                        await HttpContext.SignOutAsync();
                        await HttpContext.SignOutAsync(IdentityConstants.ApplicationScheme);
                        await HttpContext.SignOutAsync(IdentityServerConstants.DefaultCookieAuthenticationScheme);
    
                        var principal = await _claimsPrincipalFactory.CreateAsync(user);
                        await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, principal);
    
                        //var result = await _signInManager.PasswordSignInAsync(model.UserName, model.Password,
                        //    model.RememberMe, true);
    
                        await _memberManager.RecordLoginAttempt(user.Id, LoginStatusType.Success);
                        _logger.LogInformation("Login attempt for `{username}` successful.", user.UserName);
                        if (string.IsNullOrWhiteSpace(model.ReturnUrl)) return View("UserClaims");
                        return Redirect(model.ReturnUrl);
                    }
    
                    await _memberManager.RecordLoginAttempt(user.Id, LoginStatusType.Failure);
                    _logger.LogInformation("Login attempt for `{username}` but email is unconfirmed.",
                        user.UserName);
                    ModelState.AddModelError("", _localizer["UnconfirmedEmail"]);
                }
                else
                {
                    await _memberManager.RecordLoginAttempt(user.Id, LoginStatusType.Failure);
                    await _memberManager.AccessFailedAsync(user);
    
                    if (await _memberManager.IsLockedOutAsync(user))
                        _logger.LogInformation(
                            "Login attempt for `{username}` but account is locked out until {lockout}",
                            user.UserName, user.LockoutEnd);
                }
            }
            else
            {
                _logger.LogWarning("Login attempt for unknown username: {username}", model.UserName);
                ModelState.AddModelError("", _localizer["InvalidUsernameOrPassword"]);
            }
        }
    
        return View("Login", model);
    }
    
    public class MemberClaimsPrincipalFactory : UserClaimsPrincipalFactory<Member>
        {
            private readonly MemberManager _memberManager;
            private readonly OrganizationRoleManager _organizationRoleManager;
    
            public MemberClaimsPrincipalFactory(MemberManager userManager,
                OrganizationRoleManager organizationRoleManager,
                IOptions<IdentityOptions> optionsAccessor)
                : base(userManager, optionsAccessor)
            {
                _memberManager = userManager;
                _organizationRoleManager = organizationRoleManager;
            }
    
            public Organization Organization { get; set; }
    
            #region Overrides of UserClaimsPrincipalFactory<Member>
    
            public async Task<ClaimsPrincipal> CreateAsync(Member user)
            {
                if (user == null) throw new ArgumentNullException(nameof(user));
                var id = await GenerateClaimsAsync(user);
                return new ClaimsPrincipal(id);
            }
    
            #endregion
    
            protected async Task<ClaimsIdentity> GenerateClaimsAsync(Member user)
            {
                if (Organization == null) throw new NullReferenceException("Organization must have value.");
    
                var identity = await base.GenerateClaimsAsync(user);
    
                // Add Organization Details
                identity.AddClaim(new Claim("organization_id", Organization.Id.ToString()));
                identity.AddClaim(new Claim("organization_short_name", Organization.ShortName));
    
                // Add Username
                identity.AddClaim(new Claim("username", user.UserName));
    
                // Adding Role(s) and Role Claim(s)
                var roleIds = await _memberManager.GetOrganizationRoleIds(user);
                foreach (var roleId in roleIds)
                {
                    var orgRole = await _organizationRoleManager.GetRoleById(Organization.Id, roleId);
                    identity.AddClaim(new Claim("role", orgRole.Name));
                    var roleClaims = await _organizationRoleManager.GetClaimsByRoleId(orgRole.Id);
                    identity.AddClaims(roleClaims);
                }
    
    
                // Adding Member Claim(s)
                var claims = await _memberManager.GetClaimsAsync(user);
                foreach (var claim in claims)
                    identity.AddClaim(new Claim(claim.Type.ToLower(), claim.Value));
    
    
                return identity;
            }
        }
    
    import { Injectable } from '@angular/core';
    
    import { UserManager, UserManagerSettings, User } from 'oidc-client';
    import { fail } from 'assert';
    
    import { environment } from '../environments/environment';
    import { UserProfile } from '../models/userprofile';
    
    @Injectable()
    export class AuthService {
      private manager: UserManager = new UserManager(getClientSettings());
      private user: User = null;
    
      constructor() {
        this.manager.getUser().then(user => {
          this.user = user;
        });
    
        //console.log("auth.service.constructor.user=" + this.user);
        //https://github.com/IdentityModel/oidc-client-js/wiki
    
        //EVENTS - begin
        this.manager.events.addSilentRenewError(function (e) {
          console.log("silent renew error", e.message);
        });
    
        this.manager.events.addAccessTokenExpired(function () {
          if (environment.debug_mode) {
            console.log("token has expired...");
          }
          //creates a loop
          //window.location.href = "/logoff/";
        });
    
        this.manager.events.addUserLoaded(function () {
          if (environment.debug_mode) {
            console.log("user has been loaded, redirect to cases...");
          }
    
          window.location.href = "/cases/";
        });
        //EVENTS - end
    
    
      }
    
      isLoggedIn(): boolean {
        return this.user != null && !this.user.expired;
      }
    
      getUser(): any {
        return this.user;
      }
    
      isUserExpired(): boolean {
        if (this.user != null)
          return this.user.expired
        else
          return true;
      }
    
      getAccessToken(): string {
        return this.user.access_token;
      }
    
      getTokenType(): string {
        return this.user.token_type;
      }
    
      getClaims(): any {
        return this.user.profile;
      }
    
      getScopes(): any {
        return this.user.scopes;
      }
    
      startAuthentication(): Promise<void> {
        return this.manager.signinRedirect();
      }
    
      completeAuthentication(): Promise<void> {
        return this.manager.signinRedirectCallback().then(user => {
          this.user = user;
        });
      }
    
      hasPermission(permission: string, category: string, subcategory: string): boolean {
    
        let rtn: boolean = false;
    
        if (this.user != null) {
    
          let userProfile: UserProfile = this.getClaims();
    
          let claim: string = category + "__" + subcategory;
    
          let profile: string = userProfile[claim];
    
          if (profile == undefined) {
            return false;
          }
    
          if (environment.debug_mode) {
            //console.log("hasPermission, profile: " + profile);
          }
    
          if (profile.includes(permission)) {
            rtn = true;
          }
        }
    
        return rtn;
      }
    
      logout(): Promise<void> {
    
        return this.manager.signoutRedirect();
    
      }
    }
    
    export function getClientSettings(): UserManagerSettings {
      return {
        authority: environment.auth_authority,
        client_id: environment.auth_client_id,
        redirect_uri: environment.auth_redirect_uri,
        post_logout_redirect_uri: environment.auth_post_logout_redirect_uri,
        response_type: "id_token",
        scope: environment.auth_scope,
        filterProtocolClaims: true,
        loadUserInfo: true
        //metadata: {
        //  issuer: environment.auth_authority.substring(0, environment.auth_authority.length - 1),
        //  jwks_uri: environment.auth_authority + '.well-known/openid-configuration/jwks',
        //  end_session_endpoint: environment.auth_authority + 'connect/endsession',
        //  authorization_endpoint: environment.auth_authority + 'connect/authorize',
        //  userinfo_endpoint: environment.auth_authority + 'connect/userinfo'
        //}
        //automaticSilentRenew: true,
        //silent_redirect_uri: 'http://localhost:4200/silent-refresh.html'
      };
    }
    
    export const environment = {
      production: false,
      debug_mode: true,
      version: "{VERSION}",
      auth_authority: (<any>window)._env.auth_authority,
      auth_redirect_uri: (<any>window)._env.auth_redirect_uri,
      auth_post_logout_redirect_uri: (<any>window)._env.auth_post_logout_redirect_uri,
      auth_client_id: "ui-web-app",
      auth_scope: "openid organization",
    
      //APIs.
      oc_api_members_url: "api/members/",
      oc_api_appointments_url: "api/appointments/",
      oc_api_centers_url: "api/centers/",
      oc_api_organizations_url: "api/organizations/",
      oc_api_procedure_protocols_url: "api/procedureprotocols/",
      auth_api_organizations_url: "api/organizations/"
    
    };
    
    window._env = {
        auth_authority: 'http://localhost:5000/',
        auth_redirect_uri: "http://localhost:4200/auth-callback",
        auth_post_logout_redirect_uri: "http://localhost:4200/",
       };
    
    auth.service.ts

    {"sid":"a994edfc711e0729e133acbcc9cde367","sub":"6f1803fc-125e-4920-557d-08d695d06a94","auth_time":1551446274,"idp":"local","username":"me@example.com","role":"Support","amr":["pwd"]}
    
    [ValidateAntiForgeryToken]
    [HttpPost("login", Name = nameof(PostLogin))]
    public async Task<IActionResult> PostLogin(LoginViewModel model)
    {
        if (ModelState.IsValid)
        {
            var user = await _memberManager.FindByEmailAsync(model.UserName);
    
            if (user != null && !await _memberManager.IsLockedOutAsync(user))
            {
                if (await _memberManager.CheckPasswordAsync(user, model.Password))
                {
                    if (!await _memberManager.IsEmailConfirmedAsync(user))
                    {
                        await _memberManager.ResetAccessFailedCountAsync(user);
    
                        if (await _memberManager.GetTwoFactorEnabledAsync(user))
                        {
                            _logger.LogInformation(
                                "Login attempt for `{username}` successful but has 2FA/2SA Enabled.",
                                user.UserName);
                            var validProviders = await _memberManager.GetValidTwoFactorProvidersAsync(user);
                            if (validProviders.Contains(_memberManager.Options.Tokens.AuthenticatorTokenProvider))
                            {
                                //await HttpContext.SignInAsync(IdentityConstants.TwoFactorUserIdScheme)
                            }
                        }
    
    
                        if (user.Organizations.Count == 0)
                        {
                            // TODO : Build Page to inform member they have not associated organizations
                        }
                        else if (user.Organizations.Count > 1)
                        {
                            // TODO : Build Page to let member select organization they want to login into
                        }
    
                        _claimsPrincipalFactory.Organization = user.Organizations.FirstOrDefault()?.Organization;
    
                        await HttpContext.SignOutAsync();
                        await HttpContext.SignOutAsync(IdentityConstants.ApplicationScheme);
                        await HttpContext.SignOutAsync(IdentityServerConstants.DefaultCookieAuthenticationScheme);
    
                        var principal = await _claimsPrincipalFactory.CreateAsync(user);
                        await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, principal);
    
                        //var result = await _signInManager.PasswordSignInAsync(model.UserName, model.Password,
                        //    model.RememberMe, true);
    
                        await _memberManager.RecordLoginAttempt(user.Id, LoginStatusType.Success);
                        _logger.LogInformation("Login attempt for `{username}` successful.", user.UserName);
                        if (string.IsNullOrWhiteSpace(model.ReturnUrl)) return View("UserClaims");
                        return Redirect(model.ReturnUrl);
                    }
    
                    await _memberManager.RecordLoginAttempt(user.Id, LoginStatusType.Failure);
                    _logger.LogInformation("Login attempt for `{username}` but email is unconfirmed.",
                        user.UserName);
                    ModelState.AddModelError("", _localizer["UnconfirmedEmail"]);
                }
                else
                {
                    await _memberManager.RecordLoginAttempt(user.Id, LoginStatusType.Failure);
                    await _memberManager.AccessFailedAsync(user);
    
                    if (await _memberManager.IsLockedOutAsync(user))
                        _logger.LogInformation(
                            "Login attempt for `{username}` but account is locked out until {lockout}",
                            user.UserName, user.LockoutEnd);
                }
            }
            else
            {
                _logger.LogWarning("Login attempt for unknown username: {username}", model.UserName);
                ModelState.AddModelError("", _localizer["InvalidUsernameOrPassword"]);
            }
        }
    
        return View("Login", model);
    }
    
    public class MemberClaimsPrincipalFactory : UserClaimsPrincipalFactory<Member>
        {
            private readonly MemberManager _memberManager;
            private readonly OrganizationRoleManager _organizationRoleManager;
    
            public MemberClaimsPrincipalFactory(MemberManager userManager,
                OrganizationRoleManager organizationRoleManager,
                IOptions<IdentityOptions> optionsAccessor)
                : base(userManager, optionsAccessor)
            {
                _memberManager = userManager;
                _organizationRoleManager = organizationRoleManager;
            }
    
            public Organization Organization { get; set; }
    
            #region Overrides of UserClaimsPrincipalFactory<Member>
    
            public async Task<ClaimsPrincipal> CreateAsync(Member user)
            {
                if (user == null) throw new ArgumentNullException(nameof(user));
                var id = await GenerateClaimsAsync(user);
                return new ClaimsPrincipal(id);
            }
    
            #endregion
    
            protected async Task<ClaimsIdentity> GenerateClaimsAsync(Member user)
            {
                if (Organization == null) throw new NullReferenceException("Organization must have value.");
    
                var identity = await base.GenerateClaimsAsync(user);
    
                // Add Organization Details
                identity.AddClaim(new Claim("organization_id", Organization.Id.ToString()));
                identity.AddClaim(new Claim("organization_short_name", Organization.ShortName));
    
                // Add Username
                identity.AddClaim(new Claim("username", user.UserName));
    
                // Adding Role(s) and Role Claim(s)
                var roleIds = await _memberManager.GetOrganizationRoleIds(user);
                foreach (var roleId in roleIds)
                {
                    var orgRole = await _organizationRoleManager.GetRoleById(Organization.Id, roleId);
                    identity.AddClaim(new Claim("role", orgRole.Name));
                    var roleClaims = await _organizationRoleManager.GetClaimsByRoleId(orgRole.Id);
                    identity.AddClaims(roleClaims);
                }
    
    
                // Adding Member Claim(s)
                var claims = await _memberManager.GetClaimsAsync(user);
                foreach (var claim in claims)
                    identity.AddClaim(new Claim(claim.Type.ToLower(), claim.Value));
    
    
                return identity;
            }
        }
    
    import { Injectable } from '@angular/core';
    
    import { UserManager, UserManagerSettings, User } from 'oidc-client';
    import { fail } from 'assert';
    
    import { environment } from '../environments/environment';
    import { UserProfile } from '../models/userprofile';
    
    @Injectable()
    export class AuthService {
      private manager: UserManager = new UserManager(getClientSettings());
      private user: User = null;
    
      constructor() {
        this.manager.getUser().then(user => {
          this.user = user;
        });
    
        //console.log("auth.service.constructor.user=" + this.user);
        //https://github.com/IdentityModel/oidc-client-js/wiki
    
        //EVENTS - begin
        this.manager.events.addSilentRenewError(function (e) {
          console.log("silent renew error", e.message);
        });
    
        this.manager.events.addAccessTokenExpired(function () {
          if (environment.debug_mode) {
            console.log("token has expired...");
          }
          //creates a loop
          //window.location.href = "/logoff/";
        });
    
        this.manager.events.addUserLoaded(function () {
          if (environment.debug_mode) {
            console.log("user has been loaded, redirect to cases...");
          }
    
          window.location.href = "/cases/";
        });
        //EVENTS - end
    
    
      }
    
      isLoggedIn(): boolean {
        return this.user != null && !this.user.expired;
      }
    
      getUser(): any {
        return this.user;
      }
    
      isUserExpired(): boolean {
        if (this.user != null)
          return this.user.expired
        else
          return true;
      }
    
      getAccessToken(): string {
        return this.user.access_token;
      }
    
      getTokenType(): string {
        return this.user.token_type;
      }
    
      getClaims(): any {
        return this.user.profile;
      }
    
      getScopes(): any {
        return this.user.scopes;
      }
    
      startAuthentication(): Promise<void> {
        return this.manager.signinRedirect();
      }
    
      completeAuthentication(): Promise<void> {
        return this.manager.signinRedirectCallback().then(user => {
          this.user = user;
        });
      }
    
      hasPermission(permission: string, category: string, subcategory: string): boolean {
    
        let rtn: boolean = false;
    
        if (this.user != null) {
    
          let userProfile: UserProfile = this.getClaims();
    
          let claim: string = category + "__" + subcategory;
    
          let profile: string = userProfile[claim];
    
          if (profile == undefined) {
            return false;
          }
    
          if (environment.debug_mode) {
            //console.log("hasPermission, profile: " + profile);
          }
    
          if (profile.includes(permission)) {
            rtn = true;
          }
        }
    
        return rtn;
      }
    
      logout(): Promise<void> {
    
        return this.manager.signoutRedirect();
    
      }
    }
    
    export function getClientSettings(): UserManagerSettings {
      return {
        authority: environment.auth_authority,
        client_id: environment.auth_client_id,
        redirect_uri: environment.auth_redirect_uri,
        post_logout_redirect_uri: environment.auth_post_logout_redirect_uri,
        response_type: "id_token",
        scope: environment.auth_scope,
        filterProtocolClaims: true,
        loadUserInfo: true
        //metadata: {
        //  issuer: environment.auth_authority.substring(0, environment.auth_authority.length - 1),
        //  jwks_uri: environment.auth_authority + '.well-known/openid-configuration/jwks',
        //  end_session_endpoint: environment.auth_authority + 'connect/endsession',
        //  authorization_endpoint: environment.auth_authority + 'connect/authorize',
        //  userinfo_endpoint: environment.auth_authority + 'connect/userinfo'
        //}
        //automaticSilentRenew: true,
        //silent_redirect_uri: 'http://localhost:4200/silent-refresh.html'
      };
    }
    
    export const environment = {
      production: false,
      debug_mode: true,
      version: "{VERSION}",
      auth_authority: (<any>window)._env.auth_authority,
      auth_redirect_uri: (<any>window)._env.auth_redirect_uri,
      auth_post_logout_redirect_uri: (<any>window)._env.auth_post_logout_redirect_uri,
      auth_client_id: "ui-web-app",
      auth_scope: "openid organization",
    
      //APIs.
      oc_api_members_url: "api/members/",
      oc_api_appointments_url: "api/appointments/",
      oc_api_centers_url: "api/centers/",
      oc_api_organizations_url: "api/organizations/",
      oc_api_procedure_protocols_url: "api/procedureprotocols/",
      auth_api_organizations_url: "api/organizations/"
    
    };
    
    window._env = {
        auth_authority: 'http://localhost:5000/',
        auth_redirect_uri: "http://localhost:4200/auth-callback",
        auth_post_logout_redirect_uri: "http://localhost:4200/",
       };
    
    env.js

    {"sid":"a994edfc711e0729e133acbcc9cde367","sub":"6f1803fc-125e-4920-557d-08d695d06a94","auth_time":1551446274,"idp":"local","username":"me@example.com","role":"Support","amr":["pwd"]}
    
    [ValidateAntiForgeryToken]
    [HttpPost("login", Name = nameof(PostLogin))]
    public async Task<IActionResult> PostLogin(LoginViewModel model)
    {
        if (ModelState.IsValid)
        {
            var user = await _memberManager.FindByEmailAsync(model.UserName);
    
            if (user != null && !await _memberManager.IsLockedOutAsync(user))
            {
                if (await _memberManager.CheckPasswordAsync(user, model.Password))
                {
                    if (!await _memberManager.IsEmailConfirmedAsync(user))
                    {
                        await _memberManager.ResetAccessFailedCountAsync(user);
    
                        if (await _memberManager.GetTwoFactorEnabledAsync(user))
                        {
                            _logger.LogInformation(
                                "Login attempt for `{username}` successful but has 2FA/2SA Enabled.",
                                user.UserName);
                            var validProviders = await _memberManager.GetValidTwoFactorProvidersAsync(user);
                            if (validProviders.Contains(_memberManager.Options.Tokens.AuthenticatorTokenProvider))
                            {
                                //await HttpContext.SignInAsync(IdentityConstants.TwoFactorUserIdScheme)
                            }
                        }
    
    
                        if (user.Organizations.Count == 0)
                        {
                            // TODO : Build Page to inform member they have not associated organizations
                        }
                        else if (user.Organizations.Count > 1)
                        {
                            // TODO : Build Page to let member select organization they want to login into
                        }
    
                        _claimsPrincipalFactory.Organization = user.Organizations.FirstOrDefault()?.Organization;
    
                        await HttpContext.SignOutAsync();
                        await HttpContext.SignOutAsync(IdentityConstants.ApplicationScheme);
                        await HttpContext.SignOutAsync(IdentityServerConstants.DefaultCookieAuthenticationScheme);
    
                        var principal = await _claimsPrincipalFactory.CreateAsync(user);
                        await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, principal);
    
                        //var result = await _signInManager.PasswordSignInAsync(model.UserName, model.Password,
                        //    model.RememberMe, true);
    
                        await _memberManager.RecordLoginAttempt(user.Id, LoginStatusType.Success);
                        _logger.LogInformation("Login attempt for `{username}` successful.", user.UserName);
                        if (string.IsNullOrWhiteSpace(model.ReturnUrl)) return View("UserClaims");
                        return Redirect(model.ReturnUrl);
                    }
    
                    await _memberManager.RecordLoginAttempt(user.Id, LoginStatusType.Failure);
                    _logger.LogInformation("Login attempt for `{username}` but email is unconfirmed.",
                        user.UserName);
                    ModelState.AddModelError("", _localizer["UnconfirmedEmail"]);
                }
                else
                {
                    await _memberManager.RecordLoginAttempt(user.Id, LoginStatusType.Failure);
                    await _memberManager.AccessFailedAsync(user);
    
                    if (await _memberManager.IsLockedOutAsync(user))
                        _logger.LogInformation(
                            "Login attempt for `{username}` but account is locked out until {lockout}",
                            user.UserName, user.LockoutEnd);
                }
            }
            else
            {
                _logger.LogWarning("Login attempt for unknown username: {username}", model.UserName);
                ModelState.AddModelError("", _localizer["InvalidUsernameOrPassword"]);
            }
        }
    
        return View("Login", model);
    }
    
    public class MemberClaimsPrincipalFactory : UserClaimsPrincipalFactory<Member>
        {
            private readonly MemberManager _memberManager;
            private readonly OrganizationRoleManager _organizationRoleManager;
    
            public MemberClaimsPrincipalFactory(MemberManager userManager,
                OrganizationRoleManager organizationRoleManager,
                IOptions<IdentityOptions> optionsAccessor)
                : base(userManager, optionsAccessor)
            {
                _memberManager = userManager;
                _organizationRoleManager = organizationRoleManager;
            }
    
            public Organization Organization { get; set; }
    
            #region Overrides of UserClaimsPrincipalFactory<Member>
    
            public async Task<ClaimsPrincipal> CreateAsync(Member user)
            {
                if (user == null) throw new ArgumentNullException(nameof(user));
                var id = await GenerateClaimsAsync(user);
                return new ClaimsPrincipal(id);
            }
    
            #endregion
    
            protected async Task<ClaimsIdentity> GenerateClaimsAsync(Member user)
            {
                if (Organization == null) throw new NullReferenceException("Organization must have value.");
    
                var identity = await base.GenerateClaimsAsync(user);
    
                // Add Organization Details
                identity.AddClaim(new Claim("organization_id", Organization.Id.ToString()));
                identity.AddClaim(new Claim("organization_short_name", Organization.ShortName));
    
                // Add Username
                identity.AddClaim(new Claim("username", user.UserName));
    
                // Adding Role(s) and Role Claim(s)
                var roleIds = await _memberManager.GetOrganizationRoleIds(user);
                foreach (var roleId in roleIds)
                {
                    var orgRole = await _organizationRoleManager.GetRoleById(Organization.Id, roleId);
                    identity.AddClaim(new Claim("role", orgRole.Name));
                    var roleClaims = await _organizationRoleManager.GetClaimsByRoleId(orgRole.Id);
                    identity.AddClaims(roleClaims);
                }
    
    
                // Adding Member Claim(s)
                var claims = await _memberManager.GetClaimsAsync(user);
                foreach (var claim in claims)
                    identity.AddClaim(new Claim(claim.Type.ToLower(), claim.Value));
    
    
                return identity;
            }
        }
    
    import { Injectable } from '@angular/core';
    
    import { UserManager, UserManagerSettings, User } from 'oidc-client';
    import { fail } from 'assert';
    
    import { environment } from '../environments/environment';
    import { UserProfile } from '../models/userprofile';
    
    @Injectable()
    export class AuthService {
      private manager: UserManager = new UserManager(getClientSettings());
      private user: User = null;
    
      constructor() {
        this.manager.getUser().then(user => {
          this.user = user;
        });
    
        //console.log("auth.service.constructor.user=" + this.user);
        //https://github.com/IdentityModel/oidc-client-js/wiki
    
        //EVENTS - begin
        this.manager.events.addSilentRenewError(function (e) {
          console.log("silent renew error", e.message);
        });
    
        this.manager.events.addAccessTokenExpired(function () {
          if (environment.debug_mode) {
            console.log("token has expired...");
          }
          //creates a loop
          //window.location.href = "/logoff/";
        });
    
        this.manager.events.addUserLoaded(function () {
          if (environment.debug_mode) {
            console.log("user has been loaded, redirect to cases...");
          }
    
          window.location.href = "/cases/";
        });
        //EVENTS - end
    
    
      }
    
      isLoggedIn(): boolean {
        return this.user != null && !this.user.expired;
      }
    
      getUser(): any {
        return this.user;
      }
    
      isUserExpired(): boolean {
        if (this.user != null)
          return this.user.expired
        else
          return true;
      }
    
      getAccessToken(): string {
        return this.user.access_token;
      }
    
      getTokenType(): string {
        return this.user.token_type;
      }
    
      getClaims(): any {
        return this.user.profile;
      }
    
      getScopes(): any {
        return this.user.scopes;
      }
    
      startAuthentication(): Promise<void> {
        return this.manager.signinRedirect();
      }
    
      completeAuthentication(): Promise<void> {
        return this.manager.signinRedirectCallback().then(user => {
          this.user = user;
        });
      }
    
      hasPermission(permission: string, category: string, subcategory: string): boolean {
    
        let rtn: boolean = false;
    
        if (this.user != null) {
    
          let userProfile: UserProfile = this.getClaims();
    
          let claim: string = category + "__" + subcategory;
    
          let profile: string = userProfile[claim];
    
          if (profile == undefined) {
            return false;
          }
    
          if (environment.debug_mode) {
            //console.log("hasPermission, profile: " + profile);
          }
    
          if (profile.includes(permission)) {
            rtn = true;
          }
        }
    
        return rtn;
      }
    
      logout(): Promise<void> {
    
        return this.manager.signoutRedirect();
    
      }
    }
    
    export function getClientSettings(): UserManagerSettings {
      return {
        authority: environment.auth_authority,
        client_id: environment.auth_client_id,
        redirect_uri: environment.auth_redirect_uri,
        post_logout_redirect_uri: environment.auth_post_logout_redirect_uri,
        response_type: "id_token",
        scope: environment.auth_scope,
        filterProtocolClaims: true,
        loadUserInfo: true
        //metadata: {
        //  issuer: environment.auth_authority.substring(0, environment.auth_authority.length - 1),
        //  jwks_uri: environment.auth_authority + '.well-known/openid-configuration/jwks',
        //  end_session_endpoint: environment.auth_authority + 'connect/endsession',
        //  authorization_endpoint: environment.auth_authority + 'connect/authorize',
        //  userinfo_endpoint: environment.auth_authority + 'connect/userinfo'
        //}
        //automaticSilentRenew: true,
        //silent_redirect_uri: 'http://localhost:4200/silent-refresh.html'
      };
    }
    
    export const environment = {
      production: false,
      debug_mode: true,
      version: "{VERSION}",
      auth_authority: (<any>window)._env.auth_authority,
      auth_redirect_uri: (<any>window)._env.auth_redirect_uri,
      auth_post_logout_redirect_uri: (<any>window)._env.auth_post_logout_redirect_uri,
      auth_client_id: "ui-web-app",
      auth_scope: "openid organization",
    
      //APIs.
      oc_api_members_url: "api/members/",
      oc_api_appointments_url: "api/appointments/",
      oc_api_centers_url: "api/centers/",
      oc_api_organizations_url: "api/organizations/",
      oc_api_procedure_protocols_url: "api/procedureprotocols/",
      auth_api_organizations_url: "api/organizations/"
    
    };
    
    window._env = {
        auth_authority: 'http://localhost:5000/',
        auth_redirect_uri: "http://localhost:4200/auth-callback",
        auth_post_logout_redirect_uri: "http://localhost:4200/",
       };
    

    您是否使用自定义配置文件服务覆盖IdentityServer中的DefaultProfileService?我们已经扩展了配置文件服务,我们可以通过调用
    /connect/userinfo
    收回索赔,但这会带来另一个问题。一个用户可以属于多个组织,并且可以具有不同的角色,包括不同的声明,这取决于他们在哪个组织下登录。我们无法找到通过userinfo端点筛选索赔的方法,以仅使用他们在其下登录的组织。您能否验证上下文是否为UserInfoEndpoint,以及索赔是否已添加到该上下文的IssuedClaims集合?@RuardvanElburg是的,我可以在调用userinfo端点时确认我们正在将索赔分配给issuedclaims collection,但我们不知道用户此时登录的是哪个组织,因此我们无法分配特定于组织的角色(及其声明)@RuardvanElburg抱歉,我一直很忙。我们确实是在看了几眼之后才弄明白的。事实证明,有人输入了一些错误,主要是请求的作用域(应该会引发错误)和数据库中的实际标识资源名称。经过一点清理和刷新数据库后,一切都开始按预期工作。