首页 > 解决方案 > 无法使用 JWT 身份验证访问 .NET Core 中的授权内容

问题描述

我开发了一个示例应用程序,我在其中使用 JWT 身份验证来访问私有内容。

在 Postman 中获得令牌后,我也可以通过 Postman 将其传递给私有控制器操作,并且一切正常。

但是当我尝试使用SignInManager访问时,它不会工作。 User.Identity.Name并且User.Identity.IsAuthenticated始终为空

这是我的启动代码

public class Startup
{
    private AppModule appModule;
    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)
    {
        appModule = new AppModule();
        AppModule.Configuration = Configuration; //setting up of static variable

        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        string connectionSring = null;
        if (true) //(env.IsDevelopment())
            connectionSring = appModule.GetConnectionString(EuConstants.LOCAL_CONNECTION_NAME);
        else
            connectionSring = appModule.GetConnectionString(EuConstants.DEFAULT_CONNECTION_NAME);



        services.AddDbContext<ApplicationDbContext>(options =>
        {
            options.UseSqlServer(connectionSring);
        });



        /* tell the framework to use our cusom user and role classes */
        services.AddIdentity<Gn_User, Gn_Role>(options =>

        {
            options.Stores.MaxLengthForKeys = 128;
        })
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

        services.ConfigureApplicationCookie(o => {
            o.LoginPath = "/portal/login";
        });

        services.AddAuthorization();

        services.AddAuthentication(option => {
            option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            option.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(options => {
            options.SaveToken = true;
            options.RequireHttpsMetadata = true;
            options.TokenValidationParameters = new TokenValidationParameters()
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidAudience = Configuration["Jwt:Site"],
                ValidIssuer = Configuration["Jwt:Site"],
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SigningKey"]))
            };
        });


        services.AddScoped<AppModule>(sp => appModule
        );

        services.AddMvc(
            options =>
            {
                // make sure that all attributes by default required authentication
               // options.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build()));
            }
            ).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider provider)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }
        app.UseAuthentication();
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseCookiePolicy();



        // tell the application to use the authentication
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Portal}/{action=Index}/{id?}");
        });
    }
}

这是生成令牌的身份验证方法

public async Task<ActionResult> Login([FromBody] Gn_User model)
    {
        string password = "yaser@1234";
        var user = await _userManager.FindByNameAsync(model.UserName);
        if (user != null && await _userManager.CheckPasswordAsync(user, password))
        {
            var claim = new[] {
                new Claim(JwtRegisteredClaimNames.Sub, user.UserName)
            };
            var signinKey = new SymmetricSecurityKey(
              Encoding.UTF8.GetBytes(AppModule.Configuration["Jwt:SigningKey"]));

            int expiryInMinutes = Convert.ToInt32(AppModule.Configuration["Jwt:ExpiryInMinutes"]);

            var token = new JwtSecurityToken(
              issuer: AppModule.Configuration["Jwt:Site"],
              audience: AppModule.Configuration["Jwt:Site"],
              expires: DateTime.UtcNow.AddMinutes(expiryInMinutes),
              signingCredentials: new SigningCredentials(signinKey, SecurityAlgorithms.HmacSha256)
            );

            return Ok(
              new
              {
                  token = new JwtSecurityTokenHandler().WriteToken(token),
                  expiration = token.ValidTo
              });
        }
        return Unauthorized();
    }

标签: asp.netasp.net-mvcasp.net-corepostman

解决方案


您忘记将您的声明添加到您的 JWT。

public async Task<ActionResult> Login([FromBody] Gn_User model)
{
    string password = "yaser@1234";
    var user = await _userManager.FindByNameAsync(model.UserName);
    if (user != null && await _userManager.CheckPasswordAsync(user, password))
    {
        var claim = new[] {
            new Claim(JwtRegisteredClaimNames.Sub, user.UserName)
        };
        var signinKey = new SymmetricSecurityKey(
          Encoding.UTF8.GetBytes(AppModule.Configuration["Jwt:SigningKey"]));

        int expiryInMinutes = Convert.ToInt32(AppModule.Configuration["Jwt:ExpiryInMinutes"]);

        var token = new JwtSecurityToken(
          issuer: AppModule.Configuration["Jwt:Site"],
          audience: AppModule.Configuration["Jwt:Site"],
          /////////////////////////////////
          claims : claim,// Dont Forget To Add Claims To Your JWT
          /////////////////////////////////
          expires: DateTime.UtcNow.AddMinutes(expiryInMinutes),
          signingCredentials: new SigningCredentials(signinKey, SecurityAlgorithms.HmacSha256)
        );

        return Ok(
          new
          {
              token = new JwtSecurityTokenHandler().WriteToken(token),
              expiration = token.ValidTo
          });
    }
    return Unauthorized();
}

推荐阅读