Ошибка сети в XMLHttpRequest.s.onerror (oidc-client.min.js: 3) с угловым 7 и ядром Asp.net 2.2 - PullRequest
0 голосов
/ 11 декабря 2018

Попытка использовать идентификационный сервер 4 для аутентификации в asp.net core 2.2 с приложением angular 7.

oidc-login-redirect.html

<script src="https://cdnjs.cloudflare.com/ajax/libs/oidc-client/1.5.4/oidc-client.min.js"></script>
<script>
  var config = {
    userStore: new Oidc.WebStorageStateStore({ store: window.localStorage })
  };
  var mgr = new Oidc.UserManager(config);
  mgr.signinRedirectCallback().then(() => {
        window.history.replaceState({},
            window.document.title,
            window.location.origin);
        window.location = "/";
    }, error => {
        console.error(error);
    });

</script>

Сервисный код Angular Auth

export class AuthServiceJwt implements CanActivate {
    _userManager: UserManager;
    _user: User;
    constructor(public router: Router) {
        //Log.logger = console;
        var config = {
            authority: environment.authority,
            client_id: environment.client_id,
            redirect_uri: `${environment.client_root_url}assets/oidc-login-redirect.html`,
            scope: environment.scope,
            response_type: environment.response_type,
            post_logout_redirect_uri: `${environment.client_root_url}?postLogout=true`,
            userStore: new WebStorageStateStore({ store: window.localStorage }),
            automaticSilentRenew: true,
            silent_redirect_uri: `${environment.client_root_url}assets/silent-redirect.html`
        };
        this._userManager = new UserManager(config);
        this._userManager.getUser().then(user => {
            if (user && !user.expired) {
                this._user = user;
                //this.loadSecurityContext();
            }
        });
        this._userManager.events.addUserLoaded(args => {
            this._userManager.getUser().then(user => {
                this._user = user;
                //this.loadSecurityContext();
            });
        });
    }


    login(): Promise<any> {
        return this._userManager.signinRedirect();
    }
}

Environment.ts

export const environment = {
    authority: 'https://localhost:44305/',
      client_id: 'mero-rental-angular-client',
      response_type: 'id_token token',
      scope: 'openid mero-rental-client-api profile',
      client_root_url: 'http://localhost:4200/'
}

Код на стороне сервера. CustomProfileService.cs

public class CustomProfileService : IProfileService
    {
        private readonly IUserClaimsPrincipalFactory<ApplicationUserViewModel> _claimsFactory;
        private readonly UserManager<ApplicationUserViewModel> _userManager;

        public CustomProfileService(UserManager<ApplicationUserViewModel> userManager, IUserClaimsPrincipalFactory<ApplicationUserViewModel> claimsFactory)
        {
            _userManager = userManager;
            _claimsFactory = claimsFactory;
        }

        public async Task GetProfileDataAsync(ProfileDataRequestContext context)
        {
            var sub = context.Subject.GetSubjectId();
            var user = await _userManager.FindByIdAsync(sub);
            var principal = await _claimsFactory.CreateAsync(user);

            var claims = principal.Claims.ToList();

            if (user.Email == "admin@identity.localhost")
            {
                claims.Add(new Claim(JwtClaimTypes.Role, "Admin"));
            }
            context.IssuedClaims = claims;
        }

        public async Task IsActiveAsync(IsActiveContext context)
        {
            var sub = context.Subject.GetSubjectId();
            var user = await _userManager.FindByIdAsync(sub);
            context.IsActive = user != null;
        }
    }

Startup.cs

public void ConfigureServices (IServiceCollection services) {

        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
        services.AddIdentity<ApplicationUserViewModel, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();
        services.AddTransient<IProfileService, CustomProfileService>();
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        var builder = services.AddIdentityServer(options =>
        {
            options.Events.RaiseErrorEvents = true;
            options.Events.RaiseInformationEvents = true;
            options.Events.RaiseFailureEvents = true;
            options.Events.RaiseSuccessEvents = true;
        })
            .AddInMemoryIdentityResources(GetIdentityResources())
            .AddInMemoryApiResources(GetApiResources())
            .AddInMemoryClients(GetClients())
            .AddAspNetIdentity<ApplicationUserViewModel>()
            .AddProfileService<CustomProfileService>();
        builder.AddDeveloperSigningCredential();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseCors(builder =>
        {
            builder.AllowAnyOrigin()
            .AllowAnyHeader()
            .AllowAnyMethod();
        });
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
        app.UseIdentityServer();
        app.UseAuthentication();
    }

класс конфигурации

public partial class Startup
    {
        public IEnumerable<ApiResource> GetApiResources()
        {
            return new List<ApiResource>
            {
                new ApiResource( ConstantValue.ClientDashApi, ConstantValue.ClientApi)
            };
        }


        public IEnumerable<Client> GetClients()
        {
            var client = new List<Client>
            {
                new Client
                {
                     ClientId = ConstantValue.ClientId,
                    ClientName = ConstantValue.ClientName,
                    AllowedGrantTypes = GrantTypes.Implicit,
                    AllowAccessTokensViaBrowser = true,
                    RequireConsent = false,
                    RedirectUris =           { string.Format("{0}/{1}", Configuration["IdentityServerUrls:ClientUrl"], "assets/oidc-login-redirect.html"), string.Format("{0}/{1}", Configuration["IdentityServerUrls:ClientUrl"], "assets/silent-redirect.html") },
                    PostLogoutRedirectUris = { string.Format("{0}?{1}", Configuration["IdentityServerUrls:ClientUrl"] , "postLogout=true") },
                    AllowedCorsOrigins =     { Configuration["IdentityServerUrls: ClientUrl"] },

                    AllowedScopes =
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        ConstantValue.ClientDashApi
                    },
                    IdentityTokenLifetime=120,
                    AccessTokenLifetime=120

                },
            };
            return client;
        }

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

Постоянное значение

public static class ConstantValue
    {
        public const string ClientId = "mero-rental-angular-client";
        public const string ClientName = "mero-rental";
        public const string ClientDashApi = "mero-rental-client-api";
        public const string ClientApi = "Mero Rental Client API";

    }

Appsetting.json

"IdentityServerUrls": {
    "Authority": "https://localhost:5002/",
    "ClientUrl": "http://localhost:4200"
  }

Я могу успешно войти в систему и увидеть токен jwt с кодом носителя.Но в браузере продолжает появляться сообщение об ошибке, как показано ниже.

more details image

При декодировании изображения на сайте JWT.IO обнаружена приведенная ниже информация.jwt info

addede more details

Выполнено небольшое исследование - https://github.com/IdentityServer/IdentityServer4/issues/1194 https://github.com/IdentityServer/IdentityServer4/issues/1249 https://github.com/IdentityServer/IdentityServer4/issues/1608 http://docs.identityserver.io/en/latest/endpoints/userinfo.html

added debug details

Ошибки

GET https://localhost:44305/connect/userinfo net::ERR_INVALID_HTTP_RESPONSE
oidc-login-redirect.html:13 Error: Network Error
    at XMLHttpRequest.s.onerror (oidc-client.min.js:3)
mgr.signinRedirectCallback.then.error @ oidc-login-redirect.html:13
Promise.then (async)
(anonymous) @ oidc-login-redirect.html:7
...