Search code examples
azureasp.net-core-webapiazure-web-app-serviceauthorize

.Net Core Web API Basic Authentication Authorize does not work on Azure


I wrote a custom auth handler for a web API in .net core 3.0 following this tutorial by Jason Watmore. The Authorize attribute works great IIS express. However, when I publish the code to Azure Web App the Authorize attribute does not fire. There is no authentication challenge and data is returned without authentication.

Azure Authentication Authorization Settings enter image description here

Here is the custom BasicAuthenticationHandler

public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
    {
        private readonly IAPIRepo _apiRepo;

        public BasicAuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options,
                                            ILoggerFactory logger, UrlEncoder encoder, 
                                             ISystemClock clock,
                                              IAPIRepo apiRepo): base(options, logger, encoder, clock)
        {
            _apiRepo = apiRepo;
        }
        protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            //throw new NotImplementedException();
            if (!Request.Headers.ContainsKey("Authorization"))
                return AuthenticateResult.Fail("Missing Authorization Header");
            User user = null;
            try
            {
                var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]);
                var credentialBytes = Convert.FromBase64String(authHeader.Parameter);
                var credentials = Encoding.UTF8.GetString(credentialBytes).Split(new[] { ':' }, 2);
                var username = credentials[0];
                var password = credentials[1];
                user = _apiRepo.Authenticate(username, password);
            }
            catch
            {
                return AuthenticateResult.Fail("Invalid Authorization Header");
            }

            if (user == null)
                return AuthenticateResult.Fail("Invalid Username or Password");

            var claims = new[] {
                new Claim(ClaimTypes.NameIdentifier, user.User_Id.ToString()),
                new Claim(ClaimTypes.Name, user.UserName),
            };
            var identity = new ClaimsIdentity(claims, Scheme.Name);
            var principal = new ClaimsPrincipal(identity);
            var ticket = new AuthenticationTicket(principal, Scheme.Name);

            return AuthenticateResult.Success(ticket);
        }
    }

Startup.cs

  services.AddScoped<IAPIRepo, APIRepo>();

            services.AddAuthentication("BasicAuthentication")
                .AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>("BasicAuthentication", null);

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {

        app.UseRouting();

        app.UseAuthentication();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }

Edit: Difference between .net core 2.2 and 3.1. Changing the run time to 3.1 fixed the issue

enter image description here


Solution

  • It looks like you are using the Startup.cs of .NET Core 3.0 instead of 3.1 like the article is using.