I am trying to make a custom filter for my web api controllers part of a ASP.NET MVC 5 website/application to check the requests headers for a specific token which i have stored in the database. Most examples I found were containing user credentials and then the user was authenticated using identity. Not exactly what I am looking for.
This is the tutorial I found and am currently following.
The web API should only handle "external" HTTP calls, the website side will have its own controllers presently (but may be subject to change).
This filter should interface with identity 2 system already present if possible.
What I do is that I send user credentials then, assign a token to the user and then I want to use that token to authenticate the request. Is there a way I can just filter the request based on the token or do I need to use Owin identity and their token management. I am using a mobile client (currently iOS, will include android too) to make the calls. Any example or tutorial I could refer to ?
The token is currently a random combination of alphanumeric characters and symbols.
Thank you.
P.S. I can post code snippets and stuff where needed.
Edit: The HTTPRequests will be filtered based on whether they contain a token present within our database/system. Requests that do contain a token or are not present within our system will receive unauthorised error (401?)
To create a custom authentication filter in ASP.NET MVC, we need to create a class by implementing the IAuthenticationFilter Interface. This IAuthenticationFilter interface has 2 methods. Open Visual Studio 2015 or an editor of your choice and create a new project.
In order to test the Custom Authentication Filter in MVC, Let's add a Controller with the name Home within the Controllers folder. Once you create the Home Controller then copy and paste the following code in it. As you can see, we created the above Home Controller class with three action methods.
Web API provides a built-in authorization filter, AuthorizeAttribute. This filter checks whether the user is authenticated. If not, it returns HTTP status code 401 (Unauthorized), without invoking the action. You can apply the filter globally, at the controller level, or at the level of individual actions.
Web API assumes that authentication happens in the host. For web-hosting, the host is IIS, which uses HTTP modules for authentication. You can configure your project to use any of the authentication modules built in to IIS or ASP.NET, or write your own HTTP module to perform custom authentication.
Suppose you thought that sending user name and password to every request is not good.Refer my below implementation with out user name and password, since we are don't send user name and password with every request.
public class AuthenticationFilter : AuthorizationFilterAttribute
{
/// <summary>
/// read requested header and validated
/// </summary>
/// <param name="actionContext"></param>
public override void OnAuthorization(HttpActionContext actionContext)
{
var identity = FetchFromHeader(actionContext);
if(identity != null)
{
var securityService = actionContext.ControllerContext.Configuration.DependencyResolver.GetService(typeof(ILoginService)) as ILoginService;
if (securityService.TokenAuthentication(identity))
{
CurrentThread.SetPrincipal(new GenericPrincipal(new GenericIdentity(identity), null), null, null);
}
else
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
return;
}
}
else
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.BadRequest);
return;
}
base.OnAuthorization(actionContext);
}
/// <summary>
/// retrive header detail from the request
/// </summary>
/// <param name="actionContext"></param>
/// <returns></returns>
private string FetchFromHeader(HttpActionContext actionContext)
{
string requestToken = null;
var authRequest = actionContext.Request.Headers.Authorization;
if (authRequest != null && !string.IsNullOrEmpty(authRequest.Scheme) && authRequest.Scheme == "Basic")
requestToken = authRequest.Parameter;
return requestToken;
}
}
You can make this filter unit testable by injecting the service dependencies via property(property injection). For custom attributes, we don't want to pass the dependencies via constructor. We want the attribute easy to use. To rewrite what @Raj already started, it can look like this:
public class AuthenticationFilter : AuthorizationFilterAttribute
{
[Dependency]
public ILoginService LoginService { get; set; }
/// <summary>
/// read requested header and validated
/// </summary>
/// <param name="actionContext"></param>
public override void OnAuthorization(HttpActionContext actionContext)
{
var identity = FetchFromHeader(actionContext);
if (identity != null)
{
if (LoginService.TokenAuthentication(identity))
{
CurrentThread.SetPrincipal(new GenericPrincipal(new GenericIdentity(identity), null), null, null);
//IPrincipal principal = new GenericPrincipal(new GenericIdentity(identity), new string[] { "myRole" });
//Thread.CurrentPrincipal = principal;
//HttpContext.Current.User = principal;
}
else
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
return;
}
}
else
{
actionContext.Response = new HttpResponseMessage(HttpStatusCode.BadRequest);
return;
}
base.OnAuthorization(actionContext);
}
/// <summary>
/// retrive header detail from the request
/// </summary>
/// <param name="actionContext"></param>
/// <returns></returns>
private string FetchFromHeader(HttpActionContext actionContext)
{
string requestToken = null;
var authRequest = actionContext.Request.Headers.Authorization;
if (authRequest != null && !string.IsNullOrEmpty(authRequest.Scheme) && authRequest.Scheme == "Basic")
requestToken = authRequest.Parameter;
return requestToken;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With