智威汤逊和Web API(JwtAuthForWebAPI?) - 寻找一个例子 [英] JWT and Web API (JwtAuthForWebAPI?) - Looking For An Example
问题描述
可是我不得不对角朝向一个Web API项目,我想用一个JWT令牌来保护它。我已经有用户/通过验证的情况发生,所以我想我只需要实现的智威汤逊的部分。
I've got a Web API project fronted by Angular, and I want to secure it using a JWT token. I've already got user/pass validation happening, so I think i just need to implement the JWT part.
我相信我已经对定居JwtAuthForWebAPI这样使用一个例子将是巨大的。
I believe I've settled on JwtAuthForWebAPI so an example using that would be great.
我假设不饰[授权]任何方法将表现为它总是,而且装饰着[授权]任何方法将401如果由客户端传递令牌不匹配。
I assume any method not decorated with [Authorize] will behave as it always does, and that any method decorated with [Authorize] will 401 if the token passed by the client doesn't match.
我还不能弄清楚它是如何令牌在初始认证发送回客户端。
What I can't yet figure out it how to send the token back to the client upon initial authentication.
我想只使用一个特殊的字符串开始,所以我有这个code:
I'm trying to just use a magic string to begin, so I have this code:
RegisterRoutes(GlobalConfiguration.Configuration.Routes);
var builder = new SecurityTokenBuilder();
var jwtHandler = new JwtAuthenticationMessageHandler
{
AllowedAudience = "http://xxxx.com",
Issuer = "corp",
SigningToken = builder.CreateFromKey(Convert.ToBase64String(new byte[]{4,2,2,6}))
};
GlobalConfiguration.Configuration.MessageHandlers.Add(jwtHandler);
但我不知道如何得到返回给客户端开始。我想我明白如何处理这种在客户端上,但加分,如果你还可以显示这种相互作用的角度侧。
But I'm not sure how that gets back to the client initially. I think I understand how to handle this on the client, but bonus points if you can also show the Angular side of this interaction.
推荐答案
我结束,不得不采取从几个不同的地方信息创建为我的作品(在现实的解决方案,生产可行的解决方案的开端 - 但它的作品!)
I ended-up having to take a information from several different places to create a solution that works for me (in reality, the beginnings of a production viable solution - but it works!)
我摆脱JwtAuthForWebAPI的(虽然我没有从中借一块,让没有授权头的请求通过流向不被把守的WebAPI控制器方法[授权])。
I got rid of JwtAuthForWebAPI (though I did borrow one piece from it to allow requests with no Authorization header to flow through to WebAPI Controller methods not guarded by [Authorize]).
相反,我使用的是微软的智威汤逊图书馆( JSON网络令牌处理程序的Microsoft .NET框架 - 从的NuGet)
Instead I'm using Microsoft's JWT Library (JSON Web Token Handler for the Microsoft .NET Framework - from NuGet).
在我的验证方法,进行实际验证后,我创建令牌的字符串版本,并将它传递回来的认证名称(相同的用户名传递到我,在这种情况下)和角色沿,在现实中,很可能认证过程中的。
In my authentication method, after doing the actual authentication, I create the string version of the token and pass it back along with the authenticated name (the same username passed into me, in this case) and a role which, in reality, would likely be derived during authentication.
下面的方法:
[HttpPost]
public LoginResult PostSignIn([FromBody] Credentials credentials)
{
var auth = new LoginResult() { Authenticated = false };
if (TryLogon(credentials.UserName, credentials.Password))
{
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, credentials.UserName),
new Claim(ClaimTypes.Role, "Admin")
}),
AppliesToAddress = ConfigurationManager.AppSettings["JwtAllowedAudience"],
TokenIssuerName = ConfigurationManager.AppSettings["JwtValidIssuer"],
SigningCredentials = new SigningCredentials(new
InMemorySymmetricSecurityKey(JwtTokenValidationHandler.SymmetricKey),
"http://www.w3.org/2001/04/xmldsig-more#hmac-sha256",
"http://www.w3.org/2001/04/xmlenc#sha256")
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);
auth.Token = tokenString;
auth.Authenticated = true;
}
return auth;
}
更新
有一个关于处理后续请求令牌问题。我所做的就是创建一个DelegatingHandler尝试读/德code中的令牌,然后创建一个校长,并将其设置成和Thread.CurrentPrincipal中HttpContext.Current.User(你需要将其设置到两个)。最后,我装点用适当的访问限制控制器的方法。
There was a question about handling the token on subsequent requests. What I did was create a DelegatingHandler to try and read/decode the token, then create a Principal and set it into Thread.CurrentPrincipal and HttpContext.Current.User (you need to set it into both). Finally, I decorate the controller methods with the appropriate access restrictions.
这里是DelegatingHandler的肉:
Here's the meat of the DelegatingHandler:
private static bool TryRetrieveToken(HttpRequestMessage request, out string token)
{
token = null;
IEnumerable<string> authzHeaders;
if (!request.Headers.TryGetValues("Authorization", out authzHeaders) || authzHeaders.Count() > 1)
{
return false;
}
var bearerToken = authzHeaders.ElementAt(0);
token = bearerToken.StartsWith("Bearer ") ? bearerToken.Substring(7) : bearerToken;
return true;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpStatusCode statusCode;
string token;
var authHeader = request.Headers.Authorization;
if (authHeader == null)
{
// missing authorization header
return base.SendAsync(request, cancellationToken);
}
if (!TryRetrieveToken(request, out token))
{
statusCode = HttpStatusCode.Unauthorized;
return Task<HttpResponseMessage>.Factory.StartNew(() => new HttpResponseMessage(statusCode));
}
try
{
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
TokenValidationParameters validationParameters =
new TokenValidationParameters()
{
AllowedAudience = ConfigurationManager.AppSettings["JwtAllowedAudience"],
ValidIssuer = ConfigurationManager.AppSettings["JwtValidIssuer"],
SigningToken = new BinarySecretSecurityToken(SymmetricKey)
};
IPrincipal principal = tokenHandler.ValidateToken(token, validationParameters);
Thread.CurrentPrincipal = principal;
HttpContext.Current.User = principal;
return base.SendAsync(request, cancellationToken);
}
catch (SecurityTokenValidationException e)
{
statusCode = HttpStatusCode.Unauthorized;
}
catch (Exception)
{
statusCode = HttpStatusCode.InternalServerError;
}
return Task<HttpResponseMessage>.Factory.StartNew(() => new HttpResponseMessage(statusCode));
}
不要忘了将它添加到MessageHandlers管道:
Don't forget to add it into the MessageHandlers pipeline:
public static void Start()
{
GlobalConfiguration.Configuration.MessageHandlers.Add(new JwtTokenValidationHandler());
}
最后,装点您的控制器方法:
Finally, decorate your controller methods:
[Authorize(Roles = "OneRoleHere")]
[GET("/api/admin/settings/product/allorgs")]
[HttpGet]
public List<Org> GetAllOrganizations()
{
return QueryableDependencies.GetMergedOrganizations().ToList();
}
[Authorize(Roles = "ADifferentRoleHere")]
[GET("/api/admin/settings/product/allorgswithapproval")]
[HttpGet]
public List<ApprovableOrg> GetAllOrganizationsWithApproval()
{
return QueryableDependencies.GetMergedOrganizationsWithApproval().ToList();
}
这篇关于智威汤逊和Web API(JwtAuthForWebAPI?) - 寻找一个例子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!