Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Core Web API Skip Authentication

I'm writing an ASP.NET Core web application using a custom basic authentication, based on the following example: ASP.NET Core Web API Authentication Now I have an action in my user controller in order to register user. So I would like to pass this method my custom Attribute "SkipAuthAttribute" in order to say, if someone calls this method (action) you have to skip the authenticaion (the user which want to register, has no login).

But the type HttpContext has no ActionDescriptor to get the Custom Attributes of the action

Knows someone, how can I skip the authenticaion by some specific actions?

like image 273
Jimy Weiss Avatar asked Jun 21 '17 13:06

Jimy Weiss


People also ask

How do I disable authentication in Web API?

To disable host-level authentication inside the Web API pipeline, call config. SuppressHostPrincipal() in your configuration.

How do I use authorization filter in Web API?

Web API uses authorization filters to implement authorization. The Authorization filters run before the controller action. If the request is not authorized, the filter returns an error response, and the action is not invoked. Web API provides a built-in authorization filter, Authorize Attribute.

What is AllowAnonymous in Web API?

One of the new features in ASP.NET MVC 4 is the AllowAnonymous Attribute that helps you secure an entire ASP.NET MVC 4 Website or Controller while providing a convenient means of allowing anonymous users access to certain controller actions, like the login and register Actions.


1 Answers

Updated answer: You should try to write code according to framework. Middleware from example are unsuitable for ASP.NET Core MVC. Here is my example:

public class BasicAuthenticationHandler : AuthenticationHandler<BasicAuthenticationOptions>
    {
        protected override Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            var authHeader = (string)this.Request.Headers["Authorization"];

            if (!string.IsNullOrEmpty(authHeader) && authHeader.StartsWith("basic", StringComparison.OrdinalIgnoreCase))
            {
                //Extract credentials
                string encodedUsernamePassword = authHeader.Substring("Basic ".Length).Trim();
                Encoding encoding = Encoding.GetEncoding("iso-8859-1");
                string usernamePassword = encoding.GetString(Convert.FromBase64String(encodedUsernamePassword));

                int seperatorIndex = usernamePassword.IndexOf(':');

                var username = usernamePassword.Substring(0, seperatorIndex);
                var password = usernamePassword.Substring(seperatorIndex + 1);

                if (username == "test" && password == "test")
                {
                    var user = new GenericPrincipal(new GenericIdentity("User"), null);
                    var ticket = new AuthenticationTicket(user, new AuthenticationProperties(), Options.AuthenticationScheme);
                    return Task.FromResult(AuthenticateResult.Success(ticket));
                }
            }

            return Task.FromResult(AuthenticateResult.Fail("No valid user."));
        }
    }

    public class BasicAuthenticationMiddleware : AuthenticationMiddleware<BasicAuthenticationOptions>
    {
        public BasicAuthenticationMiddleware(
           RequestDelegate next,
           IOptions<BasicAuthenticationOptions> options,
           ILoggerFactory loggerFactory,
           UrlEncoder encoder)
           : base(next, options, loggerFactory, encoder)
        {
        }

        protected override AuthenticationHandler<BasicAuthenticationOptions> CreateHandler()
        {
            return new BasicAuthenticationHandler();
        }
    }

    public class BasicAuthenticationOptions : AuthenticationOptions
    {
        public BasicAuthenticationOptions()
        {
            AuthenticationScheme = "Basic";
            AutomaticAuthenticate = true;
        }
    }

Registration at Startup.cs - app.UseMiddleware<BasicAuthenticationMiddleware>();. With this code, you can restrict any controller with standart attribute Autorize:

[Authorize(ActiveAuthenticationSchemes = "Basic")]
[Route("api/[controller]")]
public class ValuesController : Controller

and use attribute AllowAnonymous if you apply authorize filter on application level.

Original answer: From documentation

Add [AllowAnonymous] to the home controller so anonymous users can get information about the site before they register.

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;

namespace ContactManager.Controllers {
[AllowAnonymous]
public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
like image 124
Ivan R. Avatar answered Sep 20 '22 05:09

Ivan R.