This is performed within the context which is called as "realm". The server includes the realm name as part of WWW-Authenticate header. Provided user credentials are valid within that realm. The scope of this realm cannot be changed or defined by the server. There are no optional authentication parameters.
How it works:
- Server returns 401 (Unauthorized) response when a request requires authentication. The response includes a WWW-Authenticate header, indicating the server supports Basic Authentication
- Client sends another request containing the client credentials as part of the Authorization header. The credentials are formatted as the string "name:password" which are of base64-encoded. These credentials are not encrypted
Advantages of using Basic Authentication:
- Relatively easy to use as it is a simple protocol
- This authentication is supported by all browsers
- Follows internet standards
Disadvantages of using Basic Authentication:
- Basic Authentication is only secure over HTTPS as credentials are sent unencrypted
- This is also vulnerable to CSRF (Cross-Site Request Forgery) attacks. Once user provides credentials, the browser automatically sends them on subsequent request within the duration of the session
- User credentials are sent in the request as plaintext with every request
- The only way to log out is by ending the browser session
- Requires anti-CSRF measures as it is vulnerable to CSRF
How to Implement: Basic Authentication can be implemented by following ways:
- Using IIS: As the user is authenticated using their Windows credentials, which means the user must have an account on the server's domain. To enable
basic authentication using IIS, set the authentication mode to "Windows" in the Web.Config of your ASP.NET project as below. In this mode, IIS uses Windows
credentials to authenticate
<system.web>
In addition to the above setting, one must enable Basic authentication in IIS. In IIS Manager, go to Features View, select Authentication and enable Basic Authentication. A client authenticates itself by setting the Authorization header in the request. Browser clients perform this step automatically. Nonbrowser clients will need to set the header
<authentication mode="Windows" />
</system.web> - With Custom Membership: As Basic Authentication uses IIS credentials which means the user accounts needs to be created for all users on the hosting
server. But for internet applications, these user accounts are typically stored in an external database. To support this scenario, HTTP module performs the
Basic Authentication. In Web API 2 world, Authentication Filter or OWIN Middleware should be used instead of HTTP module.
To enable HTTP module, make below change to Web.Config file:<system.webServer>
While using this, other authentication schemas like Forms and Windows Authentication should be disabled. Below is the implementation example
<modules>
<add name="BasicAuthHttpModule" type="WebHostBasicAuth.Modules.BasicAuthHttpModule, YourAssemblyName"/>
</modules>
</system.webServer>namespace WebHostBasicAuth.Modules
{
public class BasicAuthHttpModule : IHttpModule
{
private const string Realm = "HTTP Test Realm";
public void Init(HttpApplication context){// Register event handlers
context.AuthenticateRequest += OnApplicationAuthenticateRequest;
context.EndRequest += OnApplicationEndRequest;
}
private static void SetPrincipal(IPrincipal principal){Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
}
// TODO: Here is where you would validate the username and password.private static bool CheckPassword(string username, string password){return username == "user" && password == "password";
}
private static void AuthenticateUser(string credentials){try
{
var encoding = Encoding.GetEncoding("iso-8859-1");
credentials = encoding.GetString(Convert.FromBase64String(credentials));
int separator = credentials.IndexOf(':');
string name = credentials.Substring(0, separator);
string password = credentials.Substring(separator + 1);
if (CheckPassword(name, password))
{
var identity = new GenericIdentity(name);
SetPrincipal(new GenericPrincipal(identity, null));
}
else
{
// Invalid username or password.
HttpContext.Current.Response.StatusCode = 401;
}
}
catch (FormatException)
{
// Credentials were not formatted correctly.
HttpContext.Current.Response.StatusCode = 401;
}
}
private static void OnApplicationAuthenticateRequest(object sender, EventArgs e){var request = HttpContext.Current.Request;
var authHeader = request.Headers["Authorization"];
if (authHeader != null)
{
var authHeaderVal = AuthenticationHeaderValue.Parse(authHeader);
// RFC 2617 sec 1.2, "scheme" name is case-insensitive
if (authHeaderVal.Scheme.Equals("basic", StringComparison.OrdinalIgnoreCase) && authHeaderVal.Parameter != null)
{
AuthenticateUser(authHeaderVal.Parameter);
}
}
}
// If the request was unauthorized, add the WWW-Authenticate header// to the response.private static void OnApplicationEndRequest(object sender, EventArgs e){var response = HttpContext.Current.Response;
if (response.StatusCode == 401)
{
response.Headers.Add("WWW-Authenticate", string.Format("Basic realm=\"{0}\"", Realm));
}
}
public void Dispose(){}}
}
With this I am concluding the illustration. Feel free to share your feedback. Happy Programming !!!
No comments:
Post a Comment