C# BasicAuthentication implementation approach - asp.net

I am thinking of creating a web api application using .Net. Here is what I am thinking of how to implement this.
The application will be serving clients who's credentials I will create separately.
These credentials will be encrypted using my own private key.
I will provide them this encrypted text.
They will use this encrypted text in the Authorization header.
On the server I will implement an AuthorizationFilterAttribute.
In here I will decrypt and validate the user.
And allow it to go to the resource.
I honestly do not understand this topic in depth. Therefore I was wondering if my approach will work.
In my tests I have seen that all requests do hit the AuthorizationFilterAttribute which means I will have the chance to check credentials on every request.
Bearer Token might not work as for that I will need (my understanding) at least 2 requests one to get token and next one to get actual resource. Please guide.
Thanks

Related

Web API: Basic Authentication or HMAC over SSL?

I would like to secure a .NET Web API service. I will be using SSL, but I also need to restrict the Web API calls that each user can call depending on the user's permissions.
From what I've read, REST/HTTP is supposed to be stateless, so technically you shouldn't be able to maintain any session state, but there are some ways around that.
One is to use basic authentication. The credentials are sent with every request. While this may be okay security-wise because they're being transmitted over SSL anyway, it really isn't practical given that it would require a lot of overhead to re-authenticate against the database every time. (A possibility might be to cache them in memory, but I doubt that's the best way.)
Another could be to use an HMAC (example implementation) to control access to API calls. There is a comment in this article that says:
Just to be clear to people that are implementing this on their HTTPS services: YOU DON'T NEED TO IMPLEMENT HMAC ON SSL!!! It's a waste of time and waste of complexity for absolutely no reason. DON'T DO IT. Use Basic Auth and be done with it.
I don't agree with this for the reasons mentioned above (it is more practical to authenticate once and control using HMAC than authenticate every time).
Is it a good and effective practice to use an HMAC to provide security to Web API calls when working over SSL, or are there any points that I am missing?
The answer depends on how much you care about security.
What is this API being used for? If security is a big concern, Basic Authentication is NOT a sufficiently good choice -- even if you're using SSL.
Even if you're using SSL, an attacker who can control or get access to your initial request can pretend to be the desired HTTPS web service, and intercept your traffic easily (then get a hold of your API credentials).
A much better solution is to do several things:
Use an API key and secret.
Generate a unique ID with each request.
Generate a timestamp with each request.
Encrypt the body of your request against your API key secret.
Put the encrypted output into the HTTP_AUTHORIZATION header in the form: API_KEY_ID:<encrypted_output>
On the server side, decrypt the payload.
Compare the timestamp -- if the request was sent more than a second before -- drop it (this prevents timing attacks).
Compare the unique id -- if this request was already executed -- drop it (this prevents replay attacks).
The above strategies make it impossible for attackers to gain access to your API credentials, even if they are able to successfully man-in-the-middle your API calls.

Interacting with QuickBooks Online V3 API

I'm writing a web application (that is not to be published by Intuit on their App Center thing) to interact with QuickBooks Online (QBO) for syncing purposes, using VB.NET and ASP.NET. I'm having a hard time understanding how to do this exactly or where to start. What I understand this this:
User accesses your web application and the "Connect to QuickBooks" button (that Intuit requires for In-App authorization) is displayed.
Before the button is clicked you send a HTTP request to get OAuth request credentials using your consumer credentials.
Once the user clicks the button they get redirected to QuickBooks Online (QBO) where they can sign in and then authorize access to a certain company, giving you authorized request credentials.
QBO then redirects back to your site indicating you have authorized request credentials in which you send a HTTP request to get access credentials.
Once you have the access credentials you are basically free to interact with the QBO V3 API.
Using the access credentials you can then construct HTTP requests that send a particular HTTP method with XML/JSON in the body to perform a corresponding CRUD operation in QBO and QBO sends a response to indicate whether it was successful or not.
When your application is done interacting with QBO you simply make sure the access credentials are stored somewhere safe and let the user continue on with their life.
(Side Question: Is this correct or did I miss something or misunderstand something?)
My main question: Do you, as the app developer, even need to construct these HTTP requests or do you use their SDK or something completely different and I'm just not getting it?
I've tried to figure this out but it sounds like you're supposed to construct this all from scratch but then I look in their SDK and they have classes for all the different entity types but then their serializer doesn't serialize correctly and they talk about their DataService class and how you use that to send objects over and using some JavaScript files they host that I have only seen referenced but not explained by them, or anyone really, and information I do find seems to be outdated/deprecated and ya...
Maybe it's just that I'm new to web development and all this is way over my head right now, which very well could be.
(Off-topic-sorta: Is it me or is their site ridiculously broken? It just seems like a lot doesn't work correctly or things are just hard to navigate and find...)
Anyways, thanks for any help anyone can offer. If I need to give more details or ask a different question or something, just let me know. New to this and it's harder than I thought to ask things haha.
My main question: Do you, as the app developer, even need to construct
these HTTP requests or do you use their SDK or something completely
different and I'm just not getting it?
This is entirely up to you, the developer.
If you want to roll your own and construct your own HTTP requests, you certainly can. You almost certainly will still want to use a pre-packaged OAuth library, as OAuth is not trivial to implement.
However, you could also certainly use an existing code library/DevKit too, in which case the library/DevKit will construct the HTTP requests for you.
The DevKits should contain example code to show you how to actually do this stuff, so that might be your best place to start.
You are on right track.
First of all you need to register with IPP to get
ConsumerKey,ConsumerKey secret and Application ID.
https://developer.intuit.com/docs/0025_quickbooksapi/0010_getting_started/0020_connect/0010_from_within_your_app/implement_oauth_in_your_app
if user don't have access token then 'connect to quickbooks' button shows up otherwise you can make it hidden.
request code : https://github.com/IntuitDeveloperRelations/IPP_Sample_Code/blob/master/QuickbooksAPI/DotNet/WebForms%20application/QuickBooksApiDotNetWebFormsSampleApp/OauthGrant.aspx.cs
access code : https://github.com/IntuitDeveloperRelations/IPP_Sample_Code/blob/master/QuickbooksAPI/DotNet/WebForms%20application/QuickBooksApiDotNetWebFormsSampleApp/OauthHandler.aspx.cs
After getting accesstoken, accesskey secret and realmID (companyid) save that to your database.
make sure to encrypt.
so next time same user connect to quickbooks they don't need to go through all of the above steps.
OAuthRequestValidator oauthValidator = new OAuthRequestValidator(accessToken, accessTokenSecret, consumerKey, consumerSecret);
ServiceContext context = new ServiceContext (appToken, companyID, IntuitServicesType.QBO, oauthValidator);
https://developer.intuit.com/docs/0025_quickbooksapi/0055_devkits/0150_ipp_.net_devkit_3.0/0002_synchronous_calls/0001_data_service_apis

Asp.NET WebAPI custom authorization

I want to create a authorization mechanism for an application based on WebAPI and AngularJs.
I've seen some articles, which use BasicHttpAuthentication, but i really don't like the whole idea of sending username, and password on every request. The more it doesn't fit for me is because i want to use OpenId authentication, where you don't have username/password pair.
I'm thinking about a solution, but I don't really know how to implement it. The concept is that user is authenticated as in an usual Web application - posts a form with user / password or selects an OpenId provider. If the user is authenticated succesfully, it is placed in a static object, which stores the User object for a certain ammount of time. Next a usertoken is generated and passed to the Client Application. The client passes the token on each request to the server, if the user exists in the above mentioned static object with the appropriate authentication token it is authorized to get the data.
Firstly - Do you think this is a good approach to the problem?
Secondly - How should I pass the authentication token, WITHOUT using cookies? I guess it should sit in the request headers, like in BasicHttpAuthentication but, I really dont' know how to handle it.
BasicHttpAuthentication
I'm with you on feeling dirty about caching the username and password on the client and forever transferring it with every request. Another aspect of Basic authentication that might work against you is the lack of sign-off. Other than changing the password, you can't "invalidate" a basic authentication session. Tokens on the other hand, will typically offer an expiration date, and if you want server-side invalidation you can check the issue date and say "any tokens older than issue date xyz are invalid".
Server State
You mention "If the user is authenticated successfully, it is placed in a static object". But this is independent of the token? This sounds like you're wanting to implement server state management of authentication sessions, but this isn't strictly necessary. The token itself should be sufficient for user authentication, managing server state is another potential obstacle. Server state can become difficult to manage when you factor app-pool recycles or web-farm environments (what if you want two services to share the same authentication token, but not require communication with a central "authentication server" for storing the state / session?)
Passing Authentication Token
Headers is definitely a good place for it. Really, where else is there? Cookies, Headers, Message. Other than a browser client, cookies don't make a lot of sense, and including it in the message can muddy your message formatting a bit, so headers is the only remaining option that makes much sense in my view.
Client Implementation
You've not specified, but I suspect you're interested in calling the service from .NET? In which case System.Net.Http.HttpClient could be your friend. In particular, the DefaultRequestHeaders collection. You can use this to add a custom header to store your authentication token.
Server Implementation
When researching ASP.NET authentication recently, I learned a lot about customisation by examining the Mixed Authentication Disposition ASP.NET Module (MADAM). I wasn't interested in using MADAM as-is, but learning about it from that article and examining the source code gave me a lot of ideas of how I could insert my own authentication module into the web stack.

Backbone HTTP basic rest api authentication

I am using Backbone.js and it communicates with a stateless rest API. Some calls require authentication, through HTTP basic.
What I don't understand is, somehow I have to authenticate each request, how could I do this securely? My first thought was to have a cookie, store the username and password but this would be vulnerable?
Can this be done securely?
There are two themes to this question. One is about security and one seems to be about REST rules.
The way to do authentication securely, is to pass that data through an SSL connection. It's the only way to securely transfer data over the wire.
With regards to sending authentication using basic auth over each request (REST), not many people I know do this in reality.
There's always a big long discussion on how much security is enough security and it really depends on your application and what the purpose is. I know this isn't the definitive answer you might be looking for but I'll just give you my take and how I'm going about dealing with the issues you mention.
With RESTful apps, the story is one should authenticate each request but in real practice I find this is more a "guide" than a hard rule. Rare is the fully RESTful application that follows all the rules. I use an encrypted cookie to store the user session data with a standard authentication flow that happens once and expires in a week. Data transfers happen through SSL to prevent MITM attacks and a modified Backbone sync sends a CSRF token along with each POST, PUT, DELETE to prevent cross site request forgeries. Probably "good enough" for the social app that I am working on. Maybe not if you're doing bank wire transfers and stuff. Hope this sort of gives you a point of reference in judging what you might want to do.
Is https://github.com/fiznool/backbone.basicauth something you'd find useful?
This plugin enables access to remote resources which are protected by HTTP Basic Authentication through your Backbone Models and Collections.
How does it work?
A resource protected with HTTP Basic Authentication requires the following HTTP header to be set on every request:
Authorization: Basic
The access token is formed by taking the username and password, concatenating together with a : separator and encoding into Base64.
This plugin handles the Base64 encoding and automatically sets the Authorization header on every request which uses Backbone.sync.

Web api authentication schema

I'm implementing a rest api to using the new web api framework. This api will be consumed by other companies so we'll be adding an authentication method.
In relation to authentication, I'm thinking to implement something based on tokens. Something like this
client provide credentials to login method
system authenticate client and send a token
client uses this token on following api calls
I wonder if this schema is useful for my scenario. Operations will be mainly atomic, basically clients will periodically ping this api to get some specific data, so not sure if make sense having a session token (at some point the token should expire and not sure how to manage this).
How would you recommend to implement authentication schema for this scenario?
When you generate a token I would store it in a database with a foreign key back to the authenticated login's primary key. I would also (with the token) store the date and time it was established, and a timeout period (you could set this per token, or store it in a config). Check the token/time everytime the service is pinged by that user, then force them to reauthenticate after that time expires (by checking it against the created date stored with the token).
This would make sure that the login information is only getting transmitted after the token expires, when a new token is generated it would delete the old token record.
Am I understanding your requirements right?
Making a token based authentication scheme like this is not easy.
I don't really have an answer for how you could implement it in a good and secure way. But will offer some thoughts off the top of my head about issues you will have to deal with:
The token generation need to be well randomized and the tokens need to be "sufficiently" (for some definition of sufficient) long in order to prevent someone from simply sending a bunch of different tokens to see if he "gets a hit"
The above issues should not be too difficult to implement. But the more tricky thing to figure out is:
How you can you reliably verify that the token has not been "kidnapped".
If the token is simply some random string, then anyone who happens to "see" it in tranfer (use SSL) will be able to assume the identity of the use for which the token was generated.
The token, when received by your service will let you know that:
Your application issued the token to user/application/entity X
The token is intact (has not been changed)
Any other thing you store with the token (is it expired etc)
But it will not without further effort let you know for sure that it was sent by user/application/entity X. It could be Y who has managed to get hold of the token.
That is the case for many authentication schemes of course, so depending on just how sensitive your data is, and also on what kind of operations can be done via you service, it may not be a huge issue for you.

Resources