I have an existing API that has No Authentication. It`s a public Web API which several clients use by making simple requests.
Now, there is the need to authorize access to a certain method.
Is there any way to do this, keeping the rest of the controllers and respective methods "open" for the clients that already use this Web API?
How can i identify if the request has permissions to access this "protected" method?
What you'll need to do is add an [Authorize]
attribute to the methods you want to protect optionally using the overload that accepts one or more role names that the calling user must be in.
Then what you'll have to implement is a way to ensure that authentication data of the caller is transformed into a Principal object. Setting the Principal is generally something you don't do yourself, but instead have the framework do for you.
If you do want to provide your own interface, you can using an authentication filter implementing the System.Web.Http.Filters.IAuthenticationFilter
interface.
So what you'll get is this:
[MyAuthentication]
[Authorize]
public SomeClass MyProtectedMethod() {
return new SomeClass();
}
And then implement the MyAuthentication
attribute. Below is an example, the important thing is that you use the context of the incoming request and end up setting the context.Principal
property with a new Principal
public class MyAuthentication : ActionFilterAttribute, System.Web.Http.Filters.IAuthenticationFilter {
public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
// 1. Look for credentials in the request.
HttpRequestMessage request = context.Request;
AuthenticationHeaderValue authorization = request.Headers.Authorization;
// 2. If there are no credentials, do nothing.
if (authorization == null)
{
return;
}
// 3. If there are credentials but the filter does not recognize the
// authentication scheme, do nothing.
if (authorization.Scheme != "Basic")
{
return;
}
// 4. If there are credentials that the filter understands, try to validate them.
// 5. If the credentials are bad, set the error result.
if (String.IsNullOrEmpty(authorization.Parameter))
{
context.ErrorResult = new AuthenticationFailureResult("Missing credentials", request);
return;
}
Tuple<string, string> userNameAndPasword = ExtractUserNameAndPassword(authorization.Parameter);
if (userNameAndPasword == null)
{
context.ErrorResult = new AuthenticationFailureResult("Invalid credentials", request);
}
string userName = userNameAndPasword.Item1;
string password = userNameAndPasword.Item2;
IPrincipal principal = await AuthenticateAsync(userName, password, cancellationToken);
if (principal == null)
{
context.ErrorResult = new AuthenticationFailureResult("Invalid username or password", request);
}
// 6. If the credentials are valid, set principal.
else
{
context.Principal = principal;
}
}
... other interface methods here
}
I hope this helps you get on the right track. For more information check this post: http://www.asp.net/web-api/overview/security/authentication-filters
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