Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I override OnAuthorization in net core web api?

Earlier I achieved something like this in 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}

Now this doesn't seem to work in net core, the goal is to read the Authorization header and de-serialize it so i can pass it to my database logic that goes something like this

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

Then in my ValuesController i had something as such

[Authentication]
 public HttpResponseMessage Get()
    {

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

Now this code might be ugly but I hope it makes sense enough for readers to understand what I want to achieve.

The base idea for this is that it will be an API for my desktop app to communicate with a MySql database only. Let me know if I should clarify something!

Extra question, i can't seem to make IntelliSense work at all when using netcore is there a way to enable this or is it lacking because it's beta?

like image 590
Equate Avatar asked Jan 10 '17 11:01

Equate


People also ask

How do I bypass authorization in Web API?

If you want to allow anonymous access you can use the [AllowAnonymous] attribute. This will block access to all methods when a user is not authorized, except the GetData() method which can be called anonymously.

Which attribute is used to override required authentication?

If a user is not authenticated, or doesn't have the required user name and role, then the Authorize attribute prevents access to the method and redirects the user to the login URL.

How do I authenticate and Authorize in Web API?

The ASP.NET Web API Framework provides a built-in authorization filter attribute i.e. AuthorizeAttribute and you can use this built-in filter attribute to checks whether the user is authenticated or not. If not, then it simply returns the HTTP status code 401 Unauthorized, without invoking the controller action method.


1 Answers

You can use custom middleware as an MVC filter to accomplish this. This was announced in ASP.NET Core 1.1 (see the section on Middleware as MVC filters).

Here is some example code based on your example:

First, create your custom middleware to do the work:

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>();
    }
}

Then, create the pipeline class to use the middleware:

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

Finally, on your action method, add the filter:

[MiddlewareFilter(typeof(MyCustomAuthenticationMiddlewarePipeline))]
public HttpResponseMessage Get()
{
    var returnData = DoSomeWork();
    return this.Request.CreateResponse(HttpStatusCode.OK, returnData);
}
like image 139
M.Ob Avatar answered Nov 17 '22 17:11

M.Ob