我正在尝试为我的应用程序实现Jwt身份验证,到目前为止,我已经设法生成令牌,并且在对它进行解码时,它看起来还不错。但是,当我使用Postman尝试访问仅用于“授权”的代码区域时,出现“未授权”错误。我发现这是由于Startup.cs中的设置所致。
Startup.cs
var key = Encoding.ASCII.GetBytes(Configuration["JwtAuthentication:SecurityKey"]);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidIssuer = Configuration["JwtAuthentication:Issuer"],
ValidateIssuer = true,
ValidateLifetime = true,
ValidateAudience = true
};
});
如果将ValidateIssuer设置为false,则可以访问[Authorized]控制器,否则它将阻止我。另外,ValidateLifeTime似乎对我不起作用。即使令牌已过期,它也会继续显示结果。
这就是我在另一个类中生成令牌的方式
public class GenerateToken : Controller
{
private IConfiguration configuration;
public GenerateToken(IConfiguration configuration)
{
this.configuration = configuration;
}
public String Generate(GenerateTokenViewModel Input)
{
var tokenHandler = new JwtSecurityTokenHandler();
List<Claim> claims = new List<Claim>();
claims.Add(new Claim("UserName", Input.User.UserName));
claims.Add(new Claim("Email", Input.User.Email));
claims.Add(new Claim("PhoneNumber", Input.User.PhoneNumber));
claims.Add(new Claim("FirstName", Input.User.FirstName));
claims.Add(new Claim("LastName", Input.User.LastName));
claims.Add(new Claim("Id", Input.User.Id));
foreach (var item in Input.Roles)
{
var currentItem = new UserRoleDetailsViewModel
{
Id = item.Id,
Name = item.Name,
ApplicationId = item.ApplicationId,
ApplicationName = item.ApplicationName
};
var convertedItem = JsonConvert.SerializeObject(currentItem);
claims.Add(new Claim("Roles", convertedItem));
}
var key = Encoding.ASCII.GetBytes(configuration["JwtAuthentication:SecurityKey"]);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Issuer = configuration["JwtAuthentication:Issuer"],
Audience = configuration["JwtAuthentication:Audience"],
IssuedAt = DateTime.UtcNow,
NotBefore = DateTime.UtcNow,
Expires = DateTime.UtcNow.AddDays(7),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
var output = tokenHandler.WriteToken(token);
return output;
}
}
我不确定该如何解决。另外,是否有针对.net core 2.1生成和验证jwt的指南?
编辑:
添加了控制器
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class AccountsController : ControllerBase
{
private AccountsData accountsData;
private readonly ILogger<AccountsController> logger;
private UserRolesData userRolesData;
private GenerateToken generateToken;
public AccountsController(ILogger<AccountsController> logger, GenerateToken generateToken, AccountsData accountsData, UserRolesData userRolesData)
{
this.accountsData = accountsData;
this.logger = logger;
this.userRolesData = userRolesData;
this.generateToken = generateToken;
}
[HttpGet]
[AllowAnonymous]
[Route("Item")]
public ActionResult Item()
{
return Ok("test");
}
[HttpGet]
[Route("GetThis")]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}
[HttpPost]
[AllowAnonymous]
[Route("Authenticate")]
public ActionResult Authenticate([FromBody]AccountsDto Input)
{
LoginViewModel lvm = new LoginViewModel
{
Email = Input.Email,
Password = Input.Password
};
var user = accountsData.Authenticate(lvm);
var token = "";
if(user == null)
{
return NotFound(LoggingGlobals.NotFound);
}
else
{
var roles = userRolesData.GetUserRoles(user.Id);
GenerateTokenViewModel gtvm = new GenerateTokenViewModel
{
User = user,
Roles = roles
};
token = generateToken.Generate(gtvm);
}
return Ok(token);
}
}
答案 0 :(得分:0)
我不完全确定是什么导致您面临的问题。我确实注意到您有ValidateAudience = true
,但没有提供ValidAudience
。
无论如何,这是一个有效的演示。您可以在GitHub here上找到它。这些是最相关的代码片段。
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
var key = Encoding.ASCII.GetBytes("this-is-the-secret");
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuerSigningKey = true,
//
ValidIssuer = "my-auth-server",
ValidateIssuer = true,
//
ValidAudience = "my-resource-server",
ValidateAudience = true,
//
ValidateLifetime = true,
};
});
}
ValuesController.cs
public class ValuesController : ControllerBase
{
[HttpGet("/api/values")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public ActionResult<string> Values()
{
return $"You have authorized access";
}
[HttpGet("/api/jwt")]
public ActionResult<string> Jwt()
{
var key = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("this-is-the-secret"));
var descriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[] { /* add claims */}),
Issuer = "my-auth-server",
Audience = "my-resource-server",
SigningCredentials =
new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature),
IssuedAt = DateTime.Now,
NotBefore = DateTime.Now,
Expires = DateTime.Now.AddDays(1)
};
var jwtHandler = new JwtSecurityTokenHandler();
var token = jwtHandler.CreateToken(descriptor);
return jwtHandler.WriteToken(token);
// alternatively
// return jwtHandler.CreateEncodedJwt(descriptor);
}
}