authorization属性忽略了[AllowAnonymous]
本文关键字:AllowAnonymous 属性 authorization | 更新日期: 2023-09-27 18:19:13
我已经在我的asp.net web api设置了一个客户授权属性
全球文件: FilterConfig.RegisterHttpFilters(GlobalConfiguration.Configuration.Filters);
FilterConfig.cs
public static void RegisterHttpFilters(System.Web.Http.Filters.HttpFilterCollection filters)
{
filters.Add(new TokenAuthentication(""));
}
认证类:
public class TokenAuthentication : Attribute, IAuthenticationFilter
{
private readonly string realm;
public bool AllowMultiple { get { return false; } }
public TokenAuthentication(string realm)
{
this.realm = "realm=" + realm;
}
public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
var request = context.Request;
// Receive token from the client. Here is the example when token is in header:
string token = null;
if (request.Headers.Contains("Token"))
{
token = request.Headers.GetValues("Token").FirstOrDefault();
}
if (token != null && token != "")
{
// Get your secret key from the configuration
var secretKey = ConfigurationManager.AppSettings["JWTSecurityKey"];
try
{
//Get the Payload from the token
string jsonPayload = JWT.JsonWebToken.Decode(token, secretKey);
int separatorIndex = jsonPayload.IndexOf(';');
string userId = "";
DateTime timeIssued = DateTime.MinValue;
if (separatorIndex >= 0)
{
//userId = UTF8Encoding.UTF8.GetString(Convert.FromBase64String(jsonPayload.Substring(0, separatorIndex)));
userId = jsonPayload.Substring(1, separatorIndex - 1);
string tmpTime = jsonPayload.Substring(separatorIndex + 1, (jsonPayload.Length - separatorIndex) - 2);
timeIssued = DateTime.Parse(tmpTime);
}
short TokenTTL = 10; //minuets
//Int16.TryParse(ConfigurationManager.AppSettings["TokenTTL"],TokenTTL);
// if ((DateTime.Now.Subtract(timeIssued).TotalMinutes >= TokenTTL))
if ((DateTime.Now.Subtract(timeIssued).TotalMinutes < 0))
{
context.ErrorResult = new UnauthorizedResult(new AuthenticationHeaderValue[0], context.Request);
}
else
{
//Save user in context
var claims = new List<Claim>()
{
new Claim(ClaimTypes.Name, userId)
};
var id = new ClaimsIdentity(claims, "Basic");
var principal = new ClaimsPrincipal(new[] { id });
// Set the user name to the user id in the httpcontext which is passed to the controller
context.Principal = principal;
}
}
catch (JWT.SignatureVerificationException)
{
context.ErrorResult = new UnauthorizedResult(new AuthenticationHeaderValue[0], context.Request);
}
}
else
{
return Task.FromResult(0);
}
return Task.FromResult(0);
}
/// <summary>
///
/// </summary>
/// <param name="context"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
{
context.Result = new ResultWithChallenge(context.Result, realm);
return Task.FromResult(0);
}
}
/// <summary>
///
/// </summary>
public class ResultWithChallenge : IHttpActionResult
{
private readonly IHttpActionResult next;
private readonly string realm;
/// <summary>
/// Constructor
/// </summary>
/// <param name="next"></param>
/// <param name="realm"></param>
public ResultWithChallenge(IHttpActionResult next, string realm)
{
this.next = next;
this.realm = realm;
}
/// <summary>
///
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var res = await next.ExecuteAsync(cancellationToken);
if (res.StatusCode == HttpStatusCode.Unauthorized)
{
res.Headers.WwwAuthenticate.Add(
new AuthenticationHeaderValue("Basic", this.realm));
}
return res;
}
}
现在我的问题是这个类被调用,甚至当[AllowAnonymous]
属性应用到我的控制器的动作。
这给我带来了麻烦,特别是登录操作,因为用户还没有令牌。
我该如何纠正这个问题?
AllowAnonymous
仅适用于授权过滤器。这里有一个身份验证过滤器。使用System.Web.Http中的OverrideAuthentication
代替。
在我最初的回答中我说你必须实现身份验证的地方?我所说的是,如果您不想调用TokenAuthentication
的AuthenticateAsync
方法,请应用OverrideAuthentication
,而不是AllowAnonymous
。AllowAnonymous
只适用于授权过滤器,而不适用于身份验证过滤器。因此,在Login
操作中,您需要像这样应用OverrideAuthentication
。
public class SomeController : ApiController
{
[OverrideAuthentication]
public HttpResponeMessage Login(Dto dto)
{ }
}