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

Equ*_*ate 5 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}
Run Code Online (Sandbox Code Playgroud)

现在这似乎在 net core 中不起作用,目标是读取 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
Run Code Online (Sandbox Code Playgroud)

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

[Authentication]
 public HttpResponseMessage Get()
    {

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

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

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

额外的问题,当使用 netcore 时,我似乎根本无法使 IntelliSense 工作,有没有办法启用它,还是因为它是测试版而缺少它?

M.O*_*.Ob 5

您可以使用自定义中间件作为 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>();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

public class MyCustomAuthenticationMiddlewarePipeline
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseMyCustomAuthentication();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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