我有机会使用 .Net MVC 5 设置承载身份验证,这是我使用自定义属性设置它的方法。我认为我们需要进行一些定制以使其适用于 .Net Core
这个api需要有一个注解,在这个例子中我将它命名为BearerAuthentication,这样它就会在到达BankCreationMethod方法内部之前检查请求的header进行承载认证
[HttpPost]
[BearerAuthentication]
[Route("someurl")]
public string BankCreationMethod(string s){
}
然后创建一个自定义属性类名 BearerAuthentication,继承自 ActionFilterAttribute。对带有注释 [BearerAuthentication] 的操作的每个请求都将通过此方法 OnActionExecuting 进行检查。如果请求的header是Bearer类型并且有一个有效的token,这将返回一个有效的结果,否则将是一个HttpStatusCode.Unauthorized响应的动作。
public class BearerAuthenticationAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext context)
{
// 1. Look for credentials in the request.
HttpRequestMessage request = context.Request;
AuthenticationHeaderValue authorization = request.Headers.Authorization;
// 2. If there are no credentials, do nothing.
if (authorization == null)
{
context.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
return;
}
// 3. If there are credentials but the filter does not recognize the
// authentication scheme, do nothing.
if (authorization.Scheme != "Bearer")
{
context.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
return;
}
if (String.IsNullOrEmpty(authorization.Parameter))
{
context.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
return;
}
//4.If there are credentials that the filter understands, try to validate them.
if (!String.IsNullOrEmpty(authorization.Parameter))
{
var apiKey = string.Empty;
if (!TokenService.IsValidToken(authorization.Parameter))
{
context.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
return;
}
return;
}
}
}
检查请求中的令牌是否有效的服务以及加密令牌的算法可以使用 GenerateToken() 和 IsValidToken(string) 方法。此示例中的算法与您从 Azure 生成的 Bearer 令牌不同,但您可以以某种方式对其进行自定义以匹配您的情况:
public static class TokenService
{
public static int expireTime = 20;
public static string GenerateToken()
{
byte[] time = BitConverter.GetBytes(DateTime.UtcNow.ToBinary());
var key = Guid.NewGuid().ToString();
var salt = "somesalt";
byte[] securedKey = Encoding.ASCII.GetBytes(key + salt);
string token = Convert.ToBase64String(time.Concat(securedKey).ToArray());
return token;
}
public static bool IsValidToken(string token)
{
try
{
byte[] data = Convert.FromBase64String(token);
//default expire time is 20 mins
DateTime when = DateTime.FromBinary(BitConverter.ToInt64(data, 0));
if (when < DateTime.UtcNow.AddMinutes(-expireTime))
{
return false;
}
return true;
}
catch (Exception ex)
{
new Exception("Unauthorized!");
}
return false;
}
}
然后在 Startup.cs 文件中,设置 AuthenticationTokenProvider(在此示例中为 Microsoft.Owin.Security.Infrastructure),以便应用了解上述 TokenService 中的 GenerateToken() 方法
public class Startup
{
public void ConfigureOAuth(IAppBuilder app)
{
AuthenticationTokenProvider authTokenProvider = new AuthenticationTokenProvider();
authTokenProvider.OnCreate = (context) =>
{
context.SetToken(TokenService.GenerateToken());
};
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
Provider = new SimpleAuthorizationServerProvider(),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(TokenService.expireTime),
AccessTokenProvider = authTokenProvider,
AuthorizationCodeProvider = authTokenProvider
};
// Token Generation
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
ConfigureOAuth(app);
}
}
希望这会有所帮助!