I am attempting to configure Basic Authentication on an MVC service in an ASP.NET Core 1.1 application. I would like to indicate a service requires Basic Authentincation by adding an attribute on the service action (rather than allowing basic auth application wide). After doing some reading it seems like the appropriate way to do this is using a Middleware Filter.
The most comprehensive guide I have found on Middleware filters is here
The above post indcates that I need to create a Pipeline class as follows
public class MyPipeline
{
public void Configure(IApplicationBuilder applicationBuilder)
{
var options = // any additional configuration
//I changed this to use the "UseMiddleware"
applicationBuilder.UseMiddleware<AuthenticationMiddleware>(options);
}
}
I also need a middleware class. I have modified and example from here
public class AuthenticationMiddleware
{
private readonly RequestDelegate _next;
public AuthenticationMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
string authHeader = context.Request.Headers["Authorization"];
if (authHeader != null && authHeader.StartsWith("Basic"))
{
//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);
//Here is the tricky bit
DBAuth authenticator = new DBAuth(ConnectionString);
if(authenticator.IsAuthorized(username, password))
{
await _next.Invoke(context);
}
else
{
context.Response.StatusCode = 401; //Unauthorized
return;
}
}
else
{
// no authorization header
context.Response.StatusCode = 401; //Unauthorized
return;
}
}
}
}
Question: How do I pass the connection string to the AuthenticationMiddleware class so I can check the username and password against a database? I really want to do it via injection rather than using the Configuration.GetConnectionString() inside the Middleware class.
From the pipeline sample code it seems like options can be passed to the middleware class but I am not sure how to modify the AuthenticationMiddleware class to accept the options or what class options actually is
PS: I know Basic Authentication is bad, but this is the requirement I have been given