我已经编写了使用Jwt令牌进行身份验证的基本WebAPI。当我使用邮递员进行测试API调用时,我会成功获得一个令牌。但是,我坚持让我的MVC应用程序使用令牌进行身份验证。
这是API的控制器-
[HttpPost]
[Route("login")]
public async Task<IActionResult> Login([FromBody] LoginModel model)
{
var user = await userManager.FindByNameAsync(model.Username);
if (user != null && await userManager.CheckPasswordAsync(user, model.Password))
{
var authClaims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("YVBy0OLlMQG6VVVp1OH7Xzyr7gHuw1qvUC5dcGt3SBM="));
var token = new JwtSecurityToken(
issuer: "https://localhost:44350",
audience: "https://localhost:44350",
expires: DateTime.Now.AddHours(3),
claims: authClaims,
signingCredentials: new Microsoft.IdentityModel.Tokens.SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256)
);
return Ok(new
{
token = new JwtSecurityTokenHandler().WriteToken(token),
expiration = token.ValidTo
});
}
return Unauthorized();
}
这是WebAPI的Startup.cs-
public class Startup
{
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.AddControllers();
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = "https://localhost:44350/",
ValidIssuer = "https://localhost:44350/",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("AA873344gshtrhjLJKJSLKF8u4o8grwieot4KJHFs9847GGSD"))
};
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
SeedDB.Initialize(app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope().ServiceProvider);
}
}
我的MVC应用控制器代码如下。它成功生成了令牌,但是我无法弄清楚如何填充HttpContext.User.Identity?
[HttpPost]
public async Task<ActionResult> Index(LoginModel login)
{
string url = BaseUrl + "api/authenticate/login";
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(url);
var postTask = client.PostAsJsonAsync<LoginModel>("login", login);
postTask.Wait();
var result = postTask.Result;
if (result.IsSuccessStatusCode)
{
var user = HttpContext.User.Identity as ClaimsIdentity;
var tokenDetails = JsonConvert.DeserializeObject<Dictionary<string, string>>(result.Content.ReadAsStringAsync().Result);
var claims = new Claim[]
{
new Claim(JwtRegisteredClaimNames.Sub, login.Username, "string"),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Iat, DateTime.Now.Ticks.ToString(), ClaimValueTypes.Integer64)
};
user.AddClaims(claims);
return RedirectToAction("Index", "Home", null);
}
}
ModelState.AddModelError(string.Empty, "Server error");
return View(login);
}
这是MVC应用程序的Startup.cs
public class Startup
{
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.AddControllersWithViews();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment 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.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
答案 0 :(得分:0)
您应该在startup.cs
中添加身份验证服务并使用身份验证中间件:
services.AddAuthentication(option =>
{
option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(option =>
{
option.RequireHttpsMetadata = false;
option.SaveToken = true;
option.TokenValidationParameters = new TokenValidationParameters
{
RequireExpirationTime = true,
ValidateLifetime = true,
ValidIssuer = "Some Issuer",
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = "Some Audience",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("Security Key")),
ValidateIssuerSigningKey = true,
};
});
还将app.UseAuthentication();
添加到Configure
中的startup.cs
方法中。