如何在net core web api中覆盖OnAuthorization?

时间:2017-01-10 11:44:55

标签: asp.net-web-api asp.net-core

之前我在asp.net中实现了类似的功能

public class Authentication : AuthorizationFilterAttribute
{
    public override void OnAuthorization(HttpActionContext actionContext)
    {
        if (actionContext.Request.Headers.Authorization == null)
        {
            actionContext.Response = actionContext.Request
                .CreateResponse(HttpStatusCode.Unauthorized);
        } else
        {
            var authenticationToken = actionContext.Request.Headers
                .Authorization.Parameter;
            var decodedAuthenticationToken = Encoding.UTF8.GetString(
                Convert.FromBase64String(authenticationToken));
            var usernamePasswordArray = decodedAuthenticationToken.Split(':');
            var username = usernamePasswordArray[0];
            var password = usernamePasswordArray[1];

            if (GetUsers.GetDatabaseUsers.CheckCredentials(username, password))
            {// logic}

现在这似乎不适用于网络核心,目标是读取Authorization标头并对其进行反序列化,以便将其传递给我的数据库逻辑

public static bool CheckCredentials(string username, string password)
        {
            try
            {
                var databaseConnection = new MySqlConnection(ConnectionString);
                var queryCommand =
                    new MySqlCommand(
                        "SELECT COUNT(*) FROM users WHERE username LIKE @username AND password LIKE @password",
                        databaseConnection);// more code

然后在我的ValuesController中我有这样的东西

[Authentication]
 public HttpResponseMessage Get()
    {

        var returnData = string.Format("database model logic{0}",mydatabasehandler.sologic,
        return Request.CreateResponse(HttpStatusCode.OK, returnData);
    }

现在这段代码可能很丑,但我希望读者能够理解我想要实现的目标。

这个基本思想是它将是我的桌面应用程序的API,仅与MySql数据库通信。让我知道我是否应该澄清一些事情!

额外的问题,在使用netcore时,我似乎无法使IntelliSense正常工作是否有一种方法可以实现这一点,或者它是否缺乏因为它是beta?

1 个答案:

答案 0 :(得分:2)

您可以使用自定义中间件作为MVC过滤器来完成此任务。 这是在ASP.NET Core 1.1中公布的(参见关于中间件的部分作为MVC过滤器)。

以下是基于您的示例的一些示例代码:

首先,创建自定义中间件来完成工作:

public class MyCustomAuthenticationMiddleware
{
    private readonly RequestDelegate next;

    public MyCustomAuthenticationMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        string authoriztionHeader = context.Request.Headers["Authorization"];

        if (authoriztionHeader != null && authoriztionHeader.StartsWith("Basic"))
        {
            var encodedUsernamePassword = authoriztionHeader.Substring("Basic ".Length).Trim();
            var encoding = Encoding.GetEncoding("iso-8859-1");
            var usernamePassword = encoding.GetString(Convert.FromBase64String(encodedUsernamePassword));
            var seperatorIndex = usernamePassword.IndexOf(':');
            var username = usernamePassword.Substring(0, seperatorIndex);
            var password = usernamePassword.Substring(seperatorIndex + 1);

            if (GetUsers.GetDatabaseUsers.CheckCredentials(username, password))
            {
                // your additional logic here...

                await this.next.Invoke(context);
            }
            else
            {
                context.Response.StatusCode = 401;
            }
        }
        else
        {
            context.Response.StatusCode = 401;
        }
    }
}

public static class MyCustomAuthenticationMiddlewareExtensions
{
    public static IApplicationBuilder UseMyCustomAuthentication(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<MyCustomAuthenticationMiddleware>();
    }
}

然后,创建管道类以使用中间件:

public class MyCustomAuthenticationMiddlewarePipeline
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseMyCustomAuthentication();
    }
}

最后,在您的操作方法上,添加过滤器:

[MiddlewareFilter(typeof(MyCustomAuthenticationMiddlewarePipeline))]
public HttpResponseMessage Get()
{
    var returnData = DoSomeWork();
    return this.Request.CreateResponse(HttpStatusCode.OK, returnData);
}