I’m working on an existing single-page application consuming data from WebAPI.
Authentication is largely handled with WebSecurity and SimpleMembership via forms authentication as the application was originally built on MVC.
I know that this is bad (CSRF), and I want to fix it either by
implementing some kind of CSRF protection (preferred)
or by reimplementing Authentication and Authorization to use tokens instead of cookies.
Would implementing header validation be an adequate solution? The API is being consumed by both web and mobile clients, in case it matters.
I’m not too skilled around security and want to make sure we’re not setting ourselves up for vulnerability by using cookies here.
Well, you would have to leave cookies anyway because otherwise you wouldn't be able to authenticate returning users (they would have to authenticate every time they open the app page). (Of course there are other exotic options like using client local storage or "Flash cookies" but this is pretty much the same approach.)
To answer your question, yes, you will need to implement CSRF protection. It doesn't matter which implementation you choose: it can be the implementation that uses custom HTTP headers or additional WebAPI request params, it can be implemented using built-in anti-forgery API (described in the article you mentioned) or you can make your own implementation.
I would probably implement custom CSRF protection mechanism because this way you can make it more suitable for your SPA (for example you can send it through WebAPI response as a result of authentication operation instead of rendering it to the HTML or JS as it was suggested in the article).
Related
There are 2 WebApi Projects on different servers. One of these servers (WebApi-A) has OAuth2 authentication workflow setup with Authorization Server and all.
The another WebApi project (WebApi-B) has an end point that I would like to Authenticate through [Authorize] attribute. I don't want have a new authorization server but to utilize (WebApi-A's) authentication process just to validate the token.
From what I understand if the machine-key is same across these server. We can essentially replicate the authentication process from WebApi-A in WebApi-B without having to call WebApi-A at all.
How do I achieve this?
You could, in theory, pass through the JWT token and if your OAuth setup uses the same client secret and data store it should just work. You would have to ensure that you add the JTW token when requesting and to use some distributed cache to verify.
I would rather ask whether or not you should rather create a gateway that can handle and authenticate the requests and delegate them to the separate APIs? This feels like an identity server (http://docs.identityserver.io/en/latest/topics/apis.html) would solve your problem. Anything you do other than moving the authentication from web api A would just be a stopgap.
Duplicating the setup could work but that will mean that you have to now maintain it in two places. So I agree that doing that is less than ideal.
This is a great article that may aid you:
https://www.scottbrady91.com/OAuth/Delegation-Patterns-for-OAuth-20
This will have a lengthy answer so I will just leave you this diagram showing multiple Resource Server, Client, and a separate Authorization Server
Taken from this article Single sign-on across multiple applications (part II) which I hope could get you started.
you can use your token when login in web api and then you add the token to the header "Authorization" with bearer "your token"
Basically, I have a homework assignment which involves me creating a MVC app in Asp.Net (the standard version, not Core). I need to provide authentication using jwt, but i have to use a separate authentication server, so the token creation and validation are delegated to that server, and if a server like that already exists (perhaps a facebook or twitter authentication server using jwt), i should use it rather than create my own. I am not sure if there is a jwt authentication server which I could use, and I don't know what is the best way to handle jwt tokens, for example if i have a form that submits stuff to a controller action, how to place a jwt token in the request. Any help on this would be much appreciated!
As this is a homework assignment I'm going to try and provide a jumping off point rather than provide code samples or anything.
A JWT can be issued from another authority and used within your own application provided your application is set up to use that authority. For example, in house we use AWS Cognito to store our users, and in each of our web applications we specify that our JWT tokens are being issued by that Cognito user pool.
I've had a quick look around online for any issuers that may provide this service for free, and found the following blog post for Auth0 which boasts being able to support up to 7000 users for free (there may be hidden costs, I haven't looked into it fully)
The tutorial in the blog post seems to follow a .Net standard rather than a core implementation. Hopefully you find this useful and good luck with your assignment!
I've been tasked with enabling authentication and authorization for our project's api. The main goal is to protect the methods from misuse, however we also need to enable a developer from another company to call the methods in their code.
Being new to authentication and authorization I'm overwhelmed with the many different options available for .NET etc. Some techniques look promising until you read that they pass credentials in plain text (basic auth?) or have other issues etc... I'm just looking for a reliable and safe approach.
I'm using IIS to host the web api, and I have seen that one such option is to authenticate at the 'host level'. My supervisor has mentioned this is the preferred approach.
I have looked at many threads and videos regarding authenticating in IIS. From what I can work out, such a solution alerts the user that a certain action requires authentication and to enter their credentials.
My issues are as follows:
Given the other developer is not a member of our domain, how can they authenticate using their (windows?) credentials. Is there an alternative to windows authentication?
How will requiring authorization on certain api actions impact the function of the site normally? I.e. will I have to pass valid credentials to the api in my code, for each request?
Overall I'm just a bit uncertain on how this all works and I appreciate any advice given.
I have an asp.net application that has both MVC controllers and WebAPI controllers.
For cookie authentication I use app.UseCookieAuthentication(... middleware with DefaultAuthenticationTypes.ApplicationCookie authentication type.
For OAuth I use app.UseOAuthBearerTokens(... middleware.
For MVC routes I have used AuthorizeAttribute as global to prevent anonymous access. Interesting thing is I can get data from MVC controllers too having access token recieved through oauth.
I understand that oauth middleware sets current user while processing request with token. Now I added additional attribute for MVC part to reject users with authentication type != DefaultAuthenticationTypes.ApplicationCookie.
Now requests with tokens will work only for WebAPI. Is this a good approach or am I doing something wrong?
Is this a good approach?
Not really, its not the authentication mechanism you want to prevent, you are likely to want to restrict access to just your MVC front end, the razor templates. You could use a custom filter similar to how it is explained in this response to ASP.NET MVC preventing users from direct URL except your filter should check that Request.Url.Host is in your list of known endpoints.
using System;
using System.Web.Mvc;
using System.Web.Routing;
namespace Customer.Filters
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class PreventFromUrl : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// MVC requests will originate from the same host as the server
// external apps may not have a referrer or it will be from a different domain
// If you have your own non-mvc code, in the same domain, we trust you know what you're doing :)
if (filterContext.HttpContext.Request.UrlReferrer == null
|| filterContext.HttpContext.Request.Url.Host != filterContext.HttpContext.Request.UrlReferrer.Host)
{
return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
}
}
}
}
If a Filter does not work, consider moving your Web API to a separate project, but be aware that this is really just a security by obscurity measure, it is still possible to use cookie based authentication to obtain access to your MVC endpoints once the caller has authenticated.
Using the authentication type alone does not provide any additional security benefits, you are just saying that each route requires specific way to authenticate, you are not doing anything to deny access itself.
You are expecting all non-MVC traffic to use OAuth, but because your site supports cookies, external apps could still programmatically and legitimately use cookie based authentication and gain access to your MVC controller endpoints.
is it important to deny access to your MVC controllers?
Your application logic should always be written with security in mind, your server-side controllers should not rely on the front end to validate and sanitise user inputs, any business rules and validation expressed in the user interface should also be evaluated in the controller logic.
Perform and design validation and business rules in the back-end first, in your controllers.
Because front end scripts are executed on the client they are therefor in a much more vulnerable state. It is trivial to capture and monitor the traffic that the front end sends back to the client, there for it you can work around client-side validations by manipulating the data before sending it back to the server.
Or worse, evolving client technologies might create scenarios where your client-side scripts and logic do not evaluate the way you originally expected, accidentally allowing un-sanitised or invalid data to flow through.
When the controller performs all business rule validation, as we are conditioned to do in Web API, then in general it should not really matter if the end client is your expected MVC client or something custom written. Even if someone wrote an app to automate or impersonate a valid user, If the caller has legitimately authenticated, let them in, because they could otherwise login directly through the MVC site manually or through the API.
It is pretty easy in MVC apps to put validation in the user interface level and to skip performing the same checks in the server-side, in this scenario, or when your MVC app exposes more data than you want to allow external clients to access it can become important to deny access to these MVC routes for non-mvc callers.
In general, supporting multiple authentication mechanisms is a good approach for an API because it broadens the options that clients can use to interact with the API. So supporting multiple types of auth to access the WebAPI routes IS a good approach.
This scenario makes it easy for your front end to access data through both the MVC controllers and the WebAPI. A common scenario that I encounter is when we use the API to secure access to external files and images. we can put the URL for the resource endpoint directly into and use the auth cookie that is already in the user's browser to access through the API.
Supporting Mutliple Authentication Mechanisms or Providers will increase the attack surface of your API. This not necessarily a bad thing, but it is something to be aware of and to audit.
Increased attack surface does not automatically mean that the service is more vulnerable, but it does mean that there are more points of potential failure in your authentication.
I want to guard OData service with custom authentication associated to a user table in database. I have been obssessed with this problem and searched solutions for a long time in vain. I mean, yes, there are quite a lot articles on the web but they are just quite trivial, for example implementing IPrincipal or IHttpContext with basic authentication on. Notably, many of them can data back to 2010 where OData is not as mature as today. So I'm wondering if there is any rapid solution to database-based custom authentication.
Any guidance would be greatly appreciated!
OData and authentication (and even authorization for that matter) are unrelated for the most part by design. That doesn't mean that OData stacks can't provide good support for authentication and authorization, just that the OData protocol itself doesn't comment on it. Protocol aside, both Web API and WCF Data Services are working on getting better support here. Speaking as a member of the .NET community (and not as a Microsoft employee), I think it's reasonable to expect that as those stacks implement authorization APIs they will probably be looking to claims-based authorization. Again, I want to state explicitly that I'm not trying to hide or divulge any plans here - I'm merely speculating about where authentication and authorization are going.
In a nutshell, if I were in your shoes I'd find the easiest intersection I could between OAuth2 and claims-based authentication and make that work for now. Working out your claims and authentication now means that you only would need to consider integrating the actual authorization code later.