Custom AuthorizeAttribute - Endpoint not work

by andreas   Last Updated September 11, 2019 19:26 PM - source

I'm very new to Asp.net Core, i hope someone can help to find the problem. I have Created a Custom Authorize Attribute to check login data stored in appsettings.json The Authorize Attribute work (breakpoints hit, data correct). But after the check, the requested endpoint never hit.

I have tested if the endpoint is work without authorization. And yes it's work.

In Startup.cs i load my Logins from appsettings.json and add it to the service as singleton.

LoginModel[] logins = Configuration.GetSection("LoginUsers").Get<LoginModel[]>();
Settings setting = new Settings();
setting.LoginModels = logins;
services.AddSingleton(setting);

My AuthorizeAttribute:


[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class MyAuthorizeAttribute : AuthorizeAttribute, IAuthorizationFilter
{

    public MyAuthorizeAttribute()
    {
    }

    public void OnAuthorization(AuthorizationFilterContext context)
    {
        // get username and password from header
        string authHeader = context.HttpContext.Request.Headers["Authorization"];
        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);

        var services = context.HttpContext.RequestServices;
        var settings = services.GetService<Settings>();

        var loginfound = settings.LoginModels.Where(x => x.Username == username && x.Password == password).FirstOrDefault();


        if (loginfound == null)
        {
            context.Result = new StatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);
        }
    }
}

My Controller:

[Route("api/[controller]")]
[ApiController]
[MyAuthorize]
public class SettingsController : ControllerBase
{

    [HttpGet("checkLogin")]
    public IActionResult CheckLogin()
    {

        return Ok(true);
    }
}

My endpoint is not work anymore. What am I doing wrong? I dont have any errors.



Answers 2


It could be that the login is found and the context's result needs to be set. If that's the case then maybe the 'Authorization' header is not set properly or not at all (maybe your encoding is not right?). To find out, add an elsestatement and insert a break point on the line that traces your code execution. Do some inspection on the local variables.

if (loginfound == null)
{
    context.Result = new StatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);
}
else
{
    System.Diagnostics.Trace.WriteLine("Login found!");
    // set a result
    context.Result = new ContentResult { Content = "Login found!", ContentType = "text/plain", StatusCode = 200 };
}
Bigabdoul
Bigabdoul
September 11, 2019 19:17 PM

For using your own authorize logic with IAuthorizationFilter, you should not use with AuthorizeAttribute which will check the Authentication with default authentication schema.

Reference Tao Zhou's answer here: Asp.Net Core 2.1 - Authorize based on content in request

Stephen McDowell
Stephen McDowell
September 11, 2019 19:18 PM

Related Questions