我有一个ASP.NET Core 2.1 WebApi,在其中实现了JWT身份验证。用户调用api/authentication/authenticate
,在消息正文中传递其用户名/密码,并返回JWT作为回报,然后他们将其用于访问服务。
我还需要API接受Windows身份验证-用户将调用api/authentication/windows
且不传递任何用户信息,该服务将检查他们是否在web.config文件中列出的授权用户列表中(如果我在IIS中托管。如果是这样,则返回JWT令牌,用户可以使用该令牌访问服务。
当前我正在考虑...
api/authentication/windows
方法将从请求中获取用户名这是解决此问题的正确方法吗?
此处非常相似(未回答)的问题:Generate JWT token on successful authentication with Windows Authentication
答案 0 :(得分:1)
如果要同时启用JWT和AD身份验证,则我仍然需要针对Web api中的Active Directory验证用户的凭据(用户名/密码):
仅传递用户名无效,因为Web api中没有经过身份验证的用户上下文。
验证用户凭证后,您可以照常生成jwt令牌,例如,如果使用HS256:
private string BuildToken()
{
var claims = new[] {
new Claim(JwtRegisteredClaimNames.NameId,"name1"),
new Claim(JwtRegisteredClaimNames.Sub,"name1"),
new Claim("customer","customer1"),
new Claim(JwtRegisteredClaimNames.Email,"wuxiyuan@sina,com"),
new Claim("role","user"),
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("Youkey"));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken("name1",
"name1",
claims,
expires: DateTime.Now.AddDays(1),
signingCredentials: creds);
return new JwtSecurityTokenHandler().WriteToken(token);
}
答案 1 :(得分:0)
api/authentication/windows
的用户名,您应激活windows authentication for the asp.net core application。您可以修改web.config或启用windows authentication in IIS。 <configuration>
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="true" />
<windowsAuthentication enabled="true" />
</authentication>
</security>
</system.webServer>
</configuration>
launchSettings.json
: "iisSettings": {
"windowsAuthentication": true,
}
使匿名身份验证保持激活状态:<anonymousAuthentication enabled="
true " />
。为了使JWT身份验证对于路由api/authentication/authenticate
请确保未停用forwardWindowsAuthToken
中aspNetCore元素的属性web.config
:forwardWindowsAuthToken="true"
或由于默认值( true )
将IISIntegration添加到webHostBuilder,除非您使用默认生成器:WebHost.CreateDefaultBuilder(args)
-UseIISIntegration在此扩展方法内称为隐式。
为POST
方法添加Authorize属性,该属性将与路由api/authentication/windows
测试身份验证(发送Windows凭据):
var handler = new System.Net.Http.HttpClientHandler()
{
Credentials = System.Net.CredentialCache.DefaultCredentials
};
var httpClient = new System.Net.Http.HttpClient(handler)
{
BaseAddress = new Uri("http://localhost")
};
var response = await httpClient.PostAsync("api/authentication/windows", null);
或使用XMLHttpRequest对象:
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost/api/authentication/windows', true);
xhr.withCredentials = true;
xhr.send();
var username = HttpContext.User.FindFirst(System.Security.Claims.ClaimTypes.Name)?.Value;
var claims = new Dictionary<string, object>
{
["jti"] = Guid.NewGuid(),
["sub"] = username,
["exp"] = DateTimeOffset.UtcNow.AddMinutes(100).ToUnixTimeSeconds()
};
var secretKey = new byte[] { 164, 60, 194, 0, 161 };
var headers = new Dictionary<string, object>
{
["alg"] = "HS512",
["typ"] = "JWT"
};
var token = JWT.Encode(claims, secretKey, JwsAlgorithm.HS512, headers);