简体   繁体   English

不使用Identity的.net core 2.2应用程序的JWT身份验证

[英]JWT Authentication for .net core 2.2 application not using Identity

I'm following this article here: https://fullstackmark.com/post/13/jwt-authentication-with-aspnet-core-2-web-api-angular-5-net-core-identity-and-facebook-login and I've run into a snag where my JWT bearer token is not authorizing my user. 我在这里关注这篇文章: https//fullstackmark.com/post/13/jwt-authentication-with-aspnet-core-2-web-api-angular-5-net-core-identity-and-facebook-登录 ,我遇到了我的JWT持票人令牌没有授权我的用户的障碍。 I get a valid JWT - See screenshot: 我得到一个有效的JWT - 请参见截图: 在此输入图像描述

here's a screenshot of me calling the api to retrieve that token: 这是我调用api来检索该令牌的屏幕截图: 在此输入图像描述

And here is a screenshot of me getting a 401 in postman. 这是我在邮递员中获得401的截图。 在此输入图像描述

I've read through all of the comments on the article and some others were getting 401s for various reasons, but I've satisfied all of those issues and they are not mine. 我已经阅读了有关该文章的所有评论,其他一些人因各种原因获得了401,但我对所有这些问题感到满意并且他们不是我的。

Wondering if another set of eyes might help spot what's going on. 想知道另一组眼睛是否有助于发现正在发生的事情。 Incedentially, I'm not using Identity for my login stuff. 从根本上说,我没有使用Identity来登录我的东西。 I prefer to use my own table structure and login mechanics for that but I don't think that's the source of my issue. 我更喜欢使用自己的表结构和登录机制,但我不认为这是我的问题的根源。

Here's my startup.cs file. 这是我的startup.cs文件。 Anything jump out at anyone here? 这里有人跳出来吗? Not really sure where to go next. 不确定下一步该去哪里。

public class Startup
{
    private const string SecretKey = "iNivDmHLpUA223sqsfhqGbMRdRj1PVkH";
    private readonly SymmetricSecurityKey _signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(SecretKey));
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

        // In production, the Angular files will be served from this directory
        services.AddSpaStaticFiles(configuration =>
        {
            configuration.RootPath = "ClientApp/dist";
        });

        services.AddDbContext<MyHomeBuilderContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("MyHomeBuilderContext"))
        );

        services.AddSingleton<IJwtFactory, JwtFactory>();

        services.TryAddTransient<IHttpContextAccessor, HttpContextAccessor>();

        // jwt wire up
        // Get options from app settings
        var jwtAppSettingOptions = Configuration.GetSection(nameof(JwtIssuerOptions));

        // Configure JwtIssuerOptions
        services.Configure<JwtIssuerOptions>(options =>
        {
            options.Issuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
            options.Audience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)];
            options.SigningCredentials = new SigningCredentials(_signingKey, SecurityAlgorithms.HmacSha256);
        });

        var tokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)],

            ValidateAudience = true,
            ValidAudience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)],

            ValidateIssuerSigningKey = true,
            IssuerSigningKey = _signingKey,

            RequireExpirationTime = false,
            ValidateLifetime = true,
            ClockSkew = TimeSpan.Zero
        };

        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

        }).AddJwtBearer(configureOptions =>
        {
            configureOptions.ClaimsIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
            configureOptions.TokenValidationParameters = tokenValidationParameters;
            configureOptions.SaveToken = true;
        });

        // api user claim policy
        services.AddAuthorization(options =>
        {
            options.AddPolicy("ApiUser", policy => policy.RequireClaim(Constants.Strings.JwtClaimIdentifiers.Rol, Constants.Strings.JwtClaims.ApiAccess));
        });

        // map the email settings from appsettings.json so they can be pushed to the core project
        services.Configure<EmailSettingsModel>(Configuration.GetSection("EmailSettings"))
            .AddSingleton(jd => jd.GetRequiredService<IOptions<EmailSettingsModel>>().Value);

        // map the push notification settings from appsettings.json so they can be pushed to the core project
        services.Configure<PushSettingsModel>(Configuration.GetSection("VapidKeys"))
            .AddSingleton(jd => jd.GetRequiredService<IOptions<PushSettingsModel>>().Value);

        services.AddTransient<IEmailService, EmailService>();
        services.AddTransient<IPushService, PushService>();

        services.AddTransient<IUserRepository, UserRepositoryEFDatabase>();
        services.AddTransient<IUserService, UserService>();
        services.AddTransient<IAdapter<UserModel, User>, UserAdapter>();

        services.AddTransient<IProjectRepository, ProjectRepositoryEFDatabase>();
        services.AddTransient<IProjectService, ProjectService>();
        services.AddTransient<IAdapter<ProjectModel, Project>, ProjectAdapter>();

        services.AddTransient<IProjectFileBucketRepository, ProjectFileBucketRepositoryEFDatabase>();
        services.AddTransient<IProjectFileBucketService, ProjectFileBucketService>();
        services.AddTransient<IAdapter<ProjectFileBucketModel, ProjectFileBucket>, ProjectFileBucketAdapter>();

        services.AddTransient<IProjectFileRepository, ProjectFileRepositoryEFDatabase>();
        services.AddTransient<IProjectFileService, ProjectFileService>();
        services.AddTransient<IAdapter<ProjectFileModel, ProjectFile>, ProjectFileAdapter>();

        services.AddTransient<IDeviceRepository, DeviceRepositoryEFDatabase>();
        services.AddTransient<IDeviceService, DeviceService>();
        services.AddTransient<IAdapter<DeviceModel, Device>, DeviceAdapter>();

    }

    // 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("/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.UseSpaStaticFiles();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller}/{action=Index}/{id?}");
        });
        app.UseAuthentication();
        app.UseSpa(spa =>
        {
            // To learn more about options for serving an Angular SPA from ASP.NET Core,
            // see https://go.microsoft.com/fwlink/?linkid=864501

            spa.Options.SourcePath = "ClientApp";

            if (env.IsDevelopment())
            {
                spa.UseAngularCliServer(npmScript: "start");
            }
        });
    }
}

I greenfielded a whole new project and went through things step by step and found the culprit. 我绿化了一个全新的项目,并逐步完成了事情,找到了罪魁祸首。 Turns out there are two actually. 原来有两个。

1) In VS 2019 you have be debugging for the authorization to work. 1)在VS 2019中,您正在调试授权工作。 Not super excited about that. 对此没有超级兴奋。 I'd much rather be able to have the authorization work with the app running but not necessarily debugging - if there's a work around for this, I'd love to hear it. 我宁愿能够在应用程序运行时进行授权,但不一定要调试 - 如果有解决方法,我很乐意听到它。 2) I had my app.UseAuthentication() below some of my other declarations in Configure() and apparently order matters - can anyone explain that? 2)我的app.UseAuthentication()下面是我在Configure() app.UseAuthentication()中的一些其他声明,显然是订单问题 - 任何人都可以解释一下吗?

I'll leave this up in case someone else runs into this issue and if anyone has some ideas on my questions - request I'd love to be educated :) 我会留下这个以防其他人遇到这个问题,如果有人对我的问题有一些想法 - 请求我喜欢接受教育:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM