1

I am using Basic Authentication and I have created a Middleware for this. When I use the Authorize attribute and try to make an API call through Postman, i get 401 Unauthorize even as I am added the authorization details in Postman.

I am not sure if it is the way i am calling the controller action via postman or whether I am missing a header option in postman.

ConfigureServices

        services
            .AddAuthentication(BasicAuthenticationDefaults.AuthenticationScheme)
            .AddBasicAuthentication(GetBasicAuthenticationOptions(users));

Configure

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseMvc();
        app.UseCors("SiteCorsPolicy");
        app.UseAuthentication();
    }

Basic Authentication Implementation

    private Action<BasicAuthenticationOptions> GetBasicAuthenticationOptions(IList<UserConfiguration> users)
    {
        return options =>
        {
            options.Realm = "Public API";
            options.Events = new BasicAuthenticationEvents
            {
                OnValidatePrincipal = context =>
                {
                    var authenticatedUser = users.FirstOrDefault(u =>
                        u.Username == context.UserName && u.Password == context.Password);

                    if (authenticatedUser != null)
                    {
                        var claims = new List<Claim>
                        {
                            new Claim(ClaimTypes.Name,
                                context.UserName,
                                context.Options.ClaimsIssuer)
                        };

                        var principal = new ClaimsPrincipal(new ClaimsIdentity(claims,
                            BasicAuthenticationDefaults.AuthenticationScheme));
                        context.Principal = principal;

                        return Task.CompletedTask;
                    }

                    return Task.FromResult(AuthenticateResult.Fail("Authentication failed."));
                }
            };
        };
    }

Controller Action with Authorize

    [Authorize]
    [HttpPost]
    [Route("test")]
    public IActionResult Test()
    {
        return Json("yes");
    }

Postman request

The username and passwords are in the appsettings.json file

enter image description here

floormind
  • 1,868
  • 5
  • 31
  • 85
  • You say you've created middleware for this, but you haven't included any middleware code here. Are you using [idunno.Authentication](https://github.com/blowdart/idunno.Authentication) or have you built your own? – Kirk Larkin May 23 '18 at 11:34
  • 1
    @KirkLarkin the services.AddAuthentication is the middleware code, and in the Configure method in the Startup.cs, there is a UseAuthentication in there – floormind May 23 '18 at 11:37
  • 4
    *Don't* do that! You are storing and comparing *unhashed passwords*! Use ASP.NET Core's own mechanisms instead. This code almost guarantees you or your customer's site will be breached – Panagiotis Kanavos May 23 '18 at 11:37
  • 1
    @PanagiotisKanavos That is not the question i am asking though, the question is why is the authentication not working, regardless of whether the password is hashed or not, the authentication mechanism is returning 401 not authorised. – floormind May 23 '18 at 11:40
  • 3
    Although it's not related to the question you're asking, you will find that a lot of SO users will not want to help you write such insecure code. – Kirk Larkin May 23 '18 at 11:42
  • 2
    @ifelabolz Kirk Larkin already answered that in a roundabout way. Don't create your own. Use a provider like [idunno.Authentication](https://github.com/blowdart/idunno.Authentication/tree/master/src/idunno.Authentication.Basic). The author is on .NET's security team, and he *does* say "You really shouldn't do this". This way you'll avoid problems in the middleware itself and only have to contend with secure password storage and validation. – Panagiotis Kanavos May 23 '18 at 11:44
  • 1
    @PanagiotisKanavos firstly if you look at the stuff in the dependancy injection method and you look at idunno's implementation you'll see that this is the AspNetCore BasicAuthentication, not something I created. – floormind May 23 '18 at 11:52
  • 1
    @ifelabolz it isn't. There's no `AddBasicAuthentication` method in .NET Core 2.0, it was *removed* precisely because it's unsuitable. Blowdart addes his own extension method, [AddBasic](https://github.com/blowdart/idunno.Authentication/blob/master/src/idunno.Authentication.Basic/BasicAuthenticationExtensions.cs#L16). If that is your code, did you try *debugging* it? Does execution enter the validation delegate? Where is the code for `AddBasicAuthentication` ? – Panagiotis Kanavos May 23 '18 at 11:55
  • 1
    @PanagiotisKanavos check https://github.com/msmolka/ZNetCS.AspNetCore.Authentication.Basic – floormind May 23 '18 at 11:56
  • 2
    @ifelabolz if you don't provide all the code or don't mention the package you use, it's impossible to try and reproduce. In any case, did you try *debugging* ? What does this code do, how does it behave? Are you saying *that package* has a bug? Were you able to run the Test project in that repo? – Panagiotis Kanavos May 23 '18 at 11:58

1 Answers1

4

The issue was just because app.UseMvc(); was placed before app.UseAuthentication(); . I just had to place app.UseMvc(); after app.UseAuthentication(); and that fixed it.

floormind
  • 1,868
  • 5
  • 31
  • 85