Asp.net core 在ASP.NET内核中从API读取JWT令牌

Asp.net core 在ASP.NET内核中从API读取JWT令牌,asp.net-core,jwt,Asp.net Core,Jwt,我的设置:我已经创建并运行了一个WebAPI解决方案,该解决方案对源(当前是db)执行用户名和密码的身份验证。这将生成JWT令牌并将其返回给请求应用程序(ASP.NET Core 2.2应用程序) 大多数解决方案都谈到保护WebAPI公开的方法,但我的方法是只通过WebAPI进行身份验证。各个应用程序需要接受令牌,以便确定授权 现在的问题是:从WebAPI读取令牌(我已经做了),验证它,然后存储它,让任何/所有控制器知道有一个经过身份验证的用户(通过Authorize属性),只要令牌有效,最好的

我的设置:我已经创建并运行了一个WebAPI解决方案,该解决方案对源(当前是db)执行用户名和密码的身份验证。这将生成JWT令牌并将其返回给请求应用程序(ASP.NET Core 2.2应用程序)

大多数解决方案都谈到保护WebAPI公开的方法,但我的方法是只通过WebAPI进行身份验证。各个应用程序需要接受令牌,以便确定授权

现在的问题是:从WebAPI读取令牌(我已经做了),验证它,然后存储它,让任何/所有控制器知道有一个经过身份验证的用户(通过Authorize属性),只要令牌有效,最好的方法是什么

再调试一下,我的令牌似乎没有被添加到头中。我看到以下调试消息:

在筛选器“Microsoft.AspNet.Mvc.Filters.AuthorizeFilter”处对请求的授权失败

代码更新2-获取JWT的代码:

var client=\u httpClientFactory.CreateClient();
client.BaseAddress=新Uri(_configuration.GetSection(“SecurityApi:Url”).Value);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(新的MediaTypeWithQualityHeaderValue(“应用程序/json”);
//登录
任务响应=ValidateUserAsync(客户端、用户名、密码);
Task-tokenResult=response.Result.Content.ReadAsAsync();
如果(!response.Result.IsSuccessStatusCode)
{
if(tokenResult!=null&&tokenResult.Result!=null)
{
ModelState.addmodeleror(“,tokenResult.Result.ReasonPhrase”);
}
其他的
{
ModelState.AddModelError(“,AppStrings.InvalidLogError”);
}
返回视图();
}
JwtSecurityToken token=新的JwtSecurityToken(tokenResult.Result.token);
int用户标识;
if(int.TryParse(token.Claims.First(s=>s.Type==JwtRegisteredClaimNames.NameId).Value,out userId))
{
//加载应用程序声明
Core.Identity.UserInfo UserInfo=Core.Identity.UserLogin.GetUser(_identityCtx,userId);
Core.Identity.UserStore uStore=新的Core.Identity.UserStore(_identityCtx);
IList claims=uStore.GetClaimsAsync(userInfo,new System.Threading.CancellationToken(false)).Result;
添加(新声明(Core.Identity.PowerFleetClaims.PowerFleetBaseClaim,Core.Identity.PowerFleetClaims.BaseUri));
ClaimsIdentity ClaimsIdentity=新的ClaimsIdentity(claims,jwtbearderdefaults.AuthenticationScheme);
索赔主体=新的索赔主体(索赔实体);
//完整的
AuthenticationProperties authProperties=新的AuthenticationProperties();
authProperties.ExpiresUtc=token.ValidTo;
authProperties.AllowRefresh=false;
authProperties.IsPersistent=true;
client.DefaultRequestHeaders.Authorization=新的AuthenticationHeaderValue(JwtBearerDefaults.AuthenticationScheme,tokenResult.Result.Token);
//var stuff=HttpContext.SignInAsync(JwtBearerDefaults.AuthenticationScheme,principal,authProperties);
}
其他的
{
ModelState.AddModelError(“,AppStrings.InvalidLogError”);
返回视图();
}
返回重定向到操作(“索引”、“主页”);
启动:

private void ConfigureIdentityServices(IServiceCollection services)
    {
        services.ConfigureApplicationCookie(options => options.LoginPath = "/Login");

        //authentication token
        services.AddAuthentication(opt =>
        {
            opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddCookie(opt =>
        {
            opt.LoginPath = "/Login";
            opt.LogoutPath = "/Login/Logoff";
            opt.Cookie.Name = Configuration.GetSection("SecurityApi:CookieName").Value;
        }).AddJwtBearer(options =>
        {
            options.SaveToken = true;
            options.RequireHttpsMetadata = false;

            options.TokenValidationParameters = new TokenValidationParameters()
            {
                ValidateAudience = true,
                ValidAudience = Configuration.GetSection("SecurityApi:Issuer").Value,
                ValidateIssuer = true,
                ValidIssuer = Configuration.GetSection("SecurityApi:Issuer").Value,
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration.GetSection("SecurityApi:Key").Value)),
                ValidateLifetime = true
            };
        });

        Core.Startup authStart = new Core.Startup(this.Configuration);
        authStart.ConfigureAuthorizationServices(services);
    }
认证:

public void配置授权服务(IServiceCollection服务)
{
services.AddDbContext(options=>options.UseSqlServer(Configuration.GetConnectionString(“SecurityConn”));
services.AddScoped(f=>
{
返回f.GetService();
});
services.AddIdentityCore().AddEntityFrameworkStores().AddRoles();
services.AddTransient();
services.AddTransient();
services.AddTransient();
services.AddAuthorization(auth=>
{
auth.AddPolicy(JwtBearerDefaults.AuthenticationScheme,new AuthorizationPolicyBuilder().AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).requireAuthenticationDuser().Build());
auth.AddPolicy(PFBaseClaim,policy=>policy.requirecall(Identity.PFClaims.BaseUri));
});
}

最后,我的方法是使用安全cookie和基本声明来证明用户经过身份验证

私有void配置身份验证(IServiceCollection服务) { services.configureapplicationcokie(options=>options.LoginPath=“/Login”)

登录时:

            AuthenticationProperties authProperties = new AuthenticationProperties();
        authProperties.ExpiresUtc = token.ValidTo;
        authProperties.AllowRefresh = false;
        authProperties.IsPersistent = true;

        HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, userStore.CreateAsync(user).Result, authProperties);

        return RedirectToAction("Index", "Home");

最后,我的方法是使用安全cookie和基本声明来证明用户经过身份验证

私有void配置身份验证(IServiceCollection服务) { services.configureapplicationcokie(options=>options.LoginPath=“/Login”)

登录时:

            AuthenticationProperties authProperties = new AuthenticationProperties();
        authProperties.ExpiresUtc = token.ValidTo;
        authProperties.AllowRefresh = false;
        authProperties.IsPersistent = true;

        HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, userStore.CreateAsync(user).Result, authProperties);

        return RedirectToAction("Index", "Home");

因此,从本质上说,您的WebAPI是一个身份提供者。在其他API中,您需要设置某种承载令牌身份验证。此配置必须具备验证令牌所需的一切。有几种方法。但是。如果这是一个新项目,我强烈建议您查看Identity Server。它是一个Identity Servery提供了您所需的一切,并且它实现了OAuth和OpenId Connect,因此我们将对您进行介绍。然后,在您的其他API上进行addin身份验证非常简单。这显示了一些关于如何启用承载令牌身份验证的示例—不完全是身份服务器,只是为了进行身份验证。没有其他用于安全的API。这是ove的现有DBr 10年前,它没有使用任何ASPNET标识表。它甚至有自己的声明生成。我试图做的是使用JWT编写一个更现代的身份验证版本,并能够使用现有过程获取声明。如果您已经提供了在用户身份验证后返回JWT令牌的方法
            AuthenticationProperties authProperties = new AuthenticationProperties();
        authProperties.ExpiresUtc = token.ValidTo;
        authProperties.AllowRefresh = false;
        authProperties.IsPersistent = true;

        HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, userStore.CreateAsync(user).Result, authProperties);

        return RedirectToAction("Index", "Home");