【发布时间】:2020-01-19 04:21:26
【问题描述】:
我正在开发一个 ASP.Net Core API 项目。
有2个控制器,控制器A和B,我使用Postman将我的用户名和密码传递给控制器A的action方法,它成功返回了一个JWT。 在我将 JWT 传递给控制器 B 后,我希望得到我输入到控制器 A 中的凭证的用户名和角色信息。
下面控制器 B 中的代码显示了我获取用户信息的方式。
public async Task<ActionResult> Get()
{
var user = await _userManager.GetUserAsync(HttpContext.User);
var role = await _userManager.GetRolesAsync(user);
return Ok(user);
}
但是在我发送 JWT 之后,我得到了 null 用户。
编辑1:
我的 Startup.cs 中的 ConfigurationServices 方法:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "issuer",
ValidAudience = "audience",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("This is my super long security Key 123"))
};
});
services.AddDbContext<JWT_AuthContext>(option => option.UseSqlServer(Configuration.GetConnectionString("JWT_AuthContextConnection")));
}
IdentityHostingStartup.cs:
public class IdentityHostingStartup : IHostingStartup
{
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices((context, services) => {
services.AddDbContext<JWT_AuthContext>(options =>
options.UseSqlServer(
context.Configuration.GetConnectionString("JWT_AuthContextConnection")));
services.AddDefaultIdentity<JWT_AuthUser>()
.AddRoles<JWT_AuthRole>()
.AddEntityFrameworkStores<JWT_AuthContext>();
});
}
}
用于 JWT 生成的控制器动作(前文中的控制器 A):
[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
private UserManager<JWT_AuthUser> _userManager;
public AuthController(UserManager<JWT_AuthUser> userManager)
{
_userManager = userManager;
}
[HttpPost("token")]
public async Task<ActionResult> GetToken()
{
var header = Request.Headers["Authorization"];
if(header.ToString().StartsWith("Basic"))
{
var loginInfo = header.ToString().Substring("Basic ".Length).Trim();
var userNameAndPassword = Encoding.UTF8.GetString(Convert.FromBase64String(loginInfo)); //username:password
var userName = userNameAndPassword.Split(":")[0];
var password = userNameAndPassword.Split(":")[1];
var user = await _userManager.FindByNameAsync(userName);
if (user != null && await _userManager.CheckPasswordAsync(user,password))
{
//security key
string securityKey = "This is my super long security Key 123";
//symmetric security key
var symmetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(securityKey));
//signing credentials
var signingCredentials = new SigningCredentials(symmetricSecurityKey, SecurityAlgorithms.HmacSha256Signature);
//add claims
var claims = new List<Claim>();
//create token
var token = new JwtSecurityToken(
issuer: "issuer",
audience: "audience",
expires: DateTime.Now.AddHours(1),
claims: claims,
signingCredentials: signingCredentials
);
//return token
return Ok(new JwtSecurityTokenHandler().WriteToken(token));
}
}
return Unauthorized();
}
获取用户信息的控制器方法(前文中的控制器B):
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private UserManager<JWT_AuthUser> _userManager;
public ValuesController(UserManager<JWT_AuthUser> userManager)
{
_userManager = userManager;
}
// GET api/values
[HttpGet]
public async Task<ActionResult> Get()
{
var user = await _userManager.GetUserAsync(HttpContext.User);
var role = await _userManager.GetRolesAsync(user);
return Ok(user);
}
}
编辑 2: Startup.cs 配置
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// 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.UseAuthentication();
app.UseMvc();
}
【问题讨论】:
-
1.请出示您的
Startup.cs。 2. 还请包括您将 JWT 传递给控制器 B 的请求 -
能否分享您的
_userManager.GetRolesAsync(user);方法代码,并在调用之前检查user != null。 -
@awais,对不起,我没有得到“分享你的 _userManager.GetRolesAsync(user)”,我直接使用这段代码。
-
@itminus,是的,我已经提供了我项目的额外代码,我将 JWT 传递给控制器 B 的方式是将 JWT 复制到 Postman-Authorization-Bearer Token。
标签: c# asp.net asp.net-core asp.net-web-api jwt