这些链接对我非常有用: MessageHandlers overview Using own Principal classes
我有一个WebApi项目,需要为它提供自定义授权。特殊令牌对象被添加到前端的每个请求中。这样的事情:
SendApiRequest: function (controller, action, data, successCallback, failureCallback) {
var url = ROUTER.GetApiUrl(controller, action);
data.Token = TOKEN;
jQuery.ajax({
type: 'POST',
dataType: 'json',
url: url,
data: data,
success: function (result) {
if (typeof successCallback == 'function') {
successCallback(result);
}
},
error: function (result) {
if (typeof failureCallback == 'function') {
failureCallback(result);
}
}
});}
我有一个AuthorizationAttribute,我不知何故需要从请求中序列化Token对象。但找不到任何自动方式来做到这一点。
public class CustomAuthorizationAttribute : AuthorizeAttribute
{
public override void OnAuthorization(HttpActionContext context)
{
UserToken token = null;
//HOW TO SERIALIZE token object from context?
}
}
UserToken类看起来像这样:
public class UserToken
{
public Int64 TokenID;
public int UserID;
public string TokenValue;
public string IP;
public string Hash;
public DateTime CreatedOn;
public DateTime ActionOn;
}
所以问题是:如何从HttpActionContext序列化自定义对象?
谢谢。
答案 0 :(得分:2)
当我处理与你类似的案件时,这就是我所做的。
您可以创建 MessageHandler ,而不是创建自己的授权属性,该 MessageHandler 会检查令牌并在每次请求时对其进行验证。此消息处理程序负责填充当前线程中的 Principal ,因此Authorize属性可以按预期工作,允许授权客户端访问相关控制器/操作。
这就是我的授权消息处理程序的样子:
public class AuthMessageHandler : DelegatingHandler
{
protected ITokenProvider TokenProvider { get; private set; }
protected IPrincipalProvider PrincipalProvider { get; private set; }
public AuthMessageHandler(ITokenProvider tokenProvider, IPrincipalProvider principalProvider)
{
TokenProvider = tokenProvider;
PrincipalProvider = principalProvider;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
Identity identity = null;
string token = ExtractToken(request);
if (token != null && TokenProvider.Verify(token, out identity))
{
request.Properties.Add(Constants.IdentityKey, identity);
var principal = PrincipalProvider.CreatePrincipal(identity);
Thread.CurrentPrincipal = principal;
HttpContext.Current.User = principal;
}
return base.SendAsync(request, cancellationToken);
}
private string ExtractToken(HttpRequestMessage request)
{
IEnumerable<string> tokenValues = null;
if (request.Headers.TryGetValues(Constants.TokenHeaderKey, out tokenValues))
return tokenValues.First();
return null;
}
}
请注意:
如果您有任何疑问,请与我们联系。这看起来更简单。