Implementing an API Key with DotNetOpenAuth - c#

I need to implement authentication for some web services that we will be hosting. I want to use open standards, so I am interested in OAuth.
I will be using WebAPI for these services.
So here's where I'm running into trouble: Most (or maybe all) of the Api Key/OAuth scenerios that I have read involve (at some point or another) a user sitting in front of a screen.
I need to put together an API that a business partner will be calling. The calls will come from an automated process -- nowhere in the chain will there be a person who can be redirected to a web site with logon credentials.
However, I don't want just anyone coming around and calling my services.
So, I read about OAuth, and how it uses a shared secret to sign each request, and I think that's what I'm after. (I would either set up a session key, or could consider making one of the parameters a "ticks" value, and only accept requests within a short timeframe, etc)
I was kind of hoping that I could use DotNetOpenAuth to accomplish this (or something like it), but every example I come across begins with "the user gets redirected to a login page). I only need "2 leg" authentication.
Is there an example of using DotNetOpenAuth to do this?
Is there a better way to go?

If you are looking at OAuth 2 then the flow you are describing is the Client Credentials Grant
This kind of "two legged" / "service account" type flow is one that doesn't have a web page based flow.
DotNetOpenAuth supports the Client Credentials Grant. You can see an example of it in action here; however, be aware even though the author states it is the "Resource Owner Password Credentials" grant it is actually the Client Credentials Grant.
The blog post above was a little out of step with the latest DotNetOpenAuth code base but these are quickly identified and altered.
I believe that as it stands the DotNetOpenAuth only supports issuing a Bearer token using Http Basic authentication. There are other more exotic extensions OAuth 2 with a similar flow e.g. the JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants (but as stated this is not yet part of DotNetOpenAuth).

Related

How to set up CAS login in WPF application for API calls?

I'm building an application in WPF that is client side and will only depend on external API.
To this point I could use open API which I build in RestSharp and everything worked well. But from last week this API uses CAS authentication, so to use them I need to be authenticated. API I want to call is in external server. They have two API's and my assumption is that if I will log in on their site using CAS then I will be able to use this auth for my API calls for second API.
I'm new to SSO, CAS and security overall, so this was my first thought: I will build WebBrowser control, get returned TGC cookie and use ticket from it to use in requests I will be making. But this failed, setting cookie still got me and 401 error and from what I understand from CAS auth for now, TGC is a go to for checking if I'm an authenticated user in current session?
My next thought was to use some CAS c# library. Unfortunately all of advices / libraries focus on creating CAS in .NET projects. Is there some library which will provide a way to log in to CAS auth and then allow me to make API calls?
I hope this makes sense and I didn't messed up things completely. I'm new to secutity and I will be grateful for any help or guidance how to approach this problem. Things I have: API specification (endpoints paths) and username and password to log in to the system.

Issuing JWT token myself versus using IdentityServer4(OIDC) for Web API

https://identityserver4.readthedocs.io/en/release/intro/support.html
I currently issue tokens myself in my web api with JwtSecurityToken and I use standard ASP.NET Core middleware calling AddJwtBearer to verify the tokens. It works fine.
What advantage will give me using OpenID Connect (through IdentityServer4) over the approach described above? How to answer myself question "Do I need OpenID Connect?"
From my basic understanding about OpenID Connect, it is used to allow third parties to access your API. But I make API for myself and not for third parties and I don't know why should I favor IdentityServer/OpenIddict over my simple approach.
I read that if I want Single sign-on I should use this, but JWTs itself aren't bound to any specific domain and I can use single sign-on with just pure JWTs(they're self-contained)
I understand it implements some kind of standard for issuing tokens. (protocol). It might be good if I ever wish to expose some API to third parties. But for internal APIs? Is it worth using it?
This is my current auth flow (from https://jonhilton.net/2017/10/11/secure-your-asp.net-core-2.0-api-part-1---issuing-a-jwt/)
What I really want to implement to secure my Web API:
Login
Logout (invalidate token?)
No consent screen (want to have API only for myself), auth happens in the background in my native desktop, mobile, web app (no redirection)
Remember me feature (refresh tokens?)
Could someone clear out the fuzzy picture of OIDC/OAuth2 for me? i.e. give me some disadvantages going my own way (implementing my own flow) and advantages of using OIDC in place of my own flow.
What will it save me from doing later on (on the client-side for example), and what will not. And most particularly, is it good to start every project using standard flows like OIDC? Will it somehow benefit me in the future?
In any case you will implement OAuth2. Think of Oidc as an extension of OAuth2. The most important thing to keep in mind is seperation of concerns.
Forget Oidc, Identity Server 4 is all about authentication: "who is the user"? Consider Google login. When a user logs in for the first time, the application doesn't know the user, it only knows that Google does.
Authorization takes place on a different level and isn't really a concern of IdentityServer. For that you could take a look at PolicyServer.
So you'll need to keep the user database seperated from the application database. This doesn't mean you need another database, just don't mix contexts. If you have a relation from the "business context" to e.g. the user table in the "Identity context" then you are going to have a problem eventually.
In your setup your web api is both the resource and the identity provider. This means that every new web api you create has to be implemented as both resource and identity provider. For maintainability you could create a seperate web api that acts as an identity provider, while the web api is a resource only. You can implement something like that as long as all apps can read the token.
The same counts for the front. Why should the front have anything to do with the user? All it needs to do is pass the token in order to get the user authorized. In case of IdentityServer, the app contacts it to verify the user and receives a token. It knows nothing about credentials. This is more secure. The client app can be compromised. The credentials can be intercepted.
Having single apps with a specific concern makes things more maintainable. And it is quite easy to add a new resource without having to code when you use IdentityServer. Just add the configuration. It also allows you to add other flows in the future that are not needed at this time. And as a side note, the consent screen is optional.
The bonus is that you can implement SSO, where in your setup that could be harder, if not impossible.
So you don't have to use IdentityServer, nor Oidc. Your setup may be just fine. But if you build something, keep seperation of concerns in mind.

Secure webapi 2 without authorisation or user login

I looked everywhere for an answer about securing my webApi but always i'm pointed to OAuth or openID, but i don't want the user to login or authenticate. This is my problem:
I have a webapi which is called via Javascript to get the data in Json. This data is used in the Html of that page. (deployed on Azure)
Now i don't want someone else to get that data via Javascript or with a simple GET request. Only my html page is allowed to do so.
I'm looking for something to secure my Webapi to be only consumed by the applications i want. If i look to the OAuth and Azure stuff, people always have to login, but i want this page to be public, but only the webapi needs to be secure.
I can't check on IP, because the call is done at client side in the browser.
It is not possible to authenticate and thus secure the API to be used by a specific client (run entirely in the browser - like SPAs) app. You cannot protect the data the app sends to the API. (see for more details Protecting REST API behind SPA against data thiefs)
You could build some modules server side and then use some token based server to server communication if you do not want to introduce users and end user authentication.
Of course it is also a question of how you interpret security.
If it is just that you do not want other web apps to use the data -
CORS policies will do the job. It is unlikely that there will be more
than some isolated cases of users using a browser other than the
popular once which respect CORS.
If it is you do not want data to be mass downloaded you could
implement some client filtering based on IP. This could even be done
on the networking layer so the API do not need to be modified in any
way.
As a suggestion, you can have it secured making sure the request has some headers defined by you. For example, you can set an Authorization header with a token that only you know. You can for example, create a token based on a key that you and the webapi share, encrypt it with the time you are calling the api. The web api receives the request and:
1 - Check if the request has the token it requires;
2 - if it does, it creates a token the same way your page did;
3 - matches its token with the requests token;
If you are calling the webapi via javascript, the method may be exposed. However, it's one idea
Take a look to CORS (Cross Origin Resource Sharing), it may be your solution.
In synthesis you can allow requests to the Api only from some specific websites. Most, nearly all browsers, support it.
This is how you enable and configure it in Web Api 2.

REST service authentication

What are the best practice for implementing authentication for REST apis?
Using BASIC auth + SSL or something like https://datatracker.ietf.org/doc/html/draft-hammer-http-token-auth-01?
Are there any existing solutions available (for .NET / WebApi)?
The answer on this depends on the audience for your Web API and what you want to authenticate exactly.
Do you want to authenticate a client application that uses your Api?
Do you want to authenticate a user from your application to retrieve their data within a client application (using your Api)?
Or do you want to authenticate both the client application and the user using the client application.
Depending on what you want to authenticate you have multiple options. But always keep in mind that it is better to go with a solid solution where many client libraries are available than reinvent you own. Never do a little off this, but in your own way, chose one way of authentication, stick to it and don't break the client libraries.
Basic authentication: Is very easy to implement, but you authenticate a client app with it, not a user. This kind of authentication is nice when business trust relation needed and authentication and safety is not your very first concern. But there is no way to track a call in your API back to a certain user, just a client application. Of course you could save your user's username and password in a client application but this is a bad practice in more then a single way.
Token based authentication: Their are many ways of token authentication but the one i'm talking about here is a single token for a user which the user copies to the client application to get access to your Api. This way you can authenticate a user (who made this call in my Api?) And it is fairly easy to make and use. The withdrawal is that it is not the most secure way, requires user interaction and that a user possibly uses his Api token in more then one application. You could extend this way of authentication with basic authentication to authenticate a client. So a clientid + clientsecret + token to identify the user. But I think if you want to accomplish this it would be better to take a look at Oauth2.
OAuth2: If you want to have full access over your authentication you can go this way. It is possibly the most future proof way to go, but also requires the most work (at least at the identity provider/resource provider side. The client application has a fairly easy time implementing this with a lot available client libraries. If you go with this way of authentication (also token based) you can authenticate the client and the user, without the need to share your users username and password.
My recommendation: would be to go with Basic Authentication if this fits your case, it is easy and together with HTTPS is fairly safe. If it doesn't fit I would go with Oauth2 because it is the most solid and used standard (Instagram/Google/Facebook), gives you a lot off freedom and with a growing ecosystem gets easier and easier to implement. After all for someone implementing your API it is way more interesting to learn something about Oauth 2.0, then learn about the jgauffin way of doing things.
Reference: I would also like to invite you to have a look at Apigee's website. Api's are their business and they have quite some interesting reads. One of them is is a free ebook - Oauth the big picture which also has a interesting paragraph where they ask if you really need Oauth. (From page 16 - Is OAuth all you need for API security?)
For server-to-server APIs - APIs designed to be used only by a small number of servers –
OAuth is overkill. Having a separate set of authentication credentials for each app is a nice
feature of OAuth, but for server-to-server use, the need to log in securely using a browser,
or to implement other steps in the OAuth “dance,” gets in the way.
Instead, using a simple security standard like HTTP Basic authentication and assigning a
unique password to each app is sufficient. Two-way SSL is another good, albeit
cumbersome approach that has the advantage of stronger, more traceable authentication.
However, think ahead! Are those APIs really only going to be used by servers forever?
Exisisting Solutions: Whatever way you go leastprivilege - Dominick Baier and his nuget packages can give you a nice headstart. Implementing basic authentication using his Identitymodel is really easy. Also if you want a ready-to-go identityserver to provide you with tokens look at his identity server which does all you can think off. However if you decide to go for Oauth2 I would also have a look at DotnetOpenAuth since it is (imho) a bit more configurable and easier to tweak to your own like, but it also takes more work.
You should look into Security Token Service or STS.
Check out these links for more information:
Off-the-shelf Security Token Service (STS) that uses ASP.NET membership provider?
http://msdn.microsoft.com/en-us/library/ee517259.aspx
You could have a look here, IdentityModel has Web API support:
http://thinktecture.github.com/Thinktecture.IdentityModel.45/

DotNetOpenAuth - request access token immediately

Ok - I'm a DotNetOpenAuth newb, just to get that out of the way.
Here's a little overview first
I'm building an app that will be an OAuth consumer of another app. This other app has what they call an "App Marketplace" where users who are logged into their site can launch consumer sites directly. This marketplace will contain a link to our app - and when clicked on will already contain the request token and request token secret. With that said, we obviously don't have to make the OAuth request to get the request token, etc, because we already have it.
Now - here's my problem
From what I can tell - DotNetOpenAuth doesn't seem to contain a way to skip the first couple of requests in the authorization process and go straight to the request to get the access token. Now, obviously, I can build my own HttpWebRequest to get it, but I was hoping to not have to do that since DotNetOpenAuth hides all that messy Authorization header stuff out of plain sight. So, anyone know of any way to skip to the access token step going through DotNetOpenAuth?
I tried calling WebConsumer.Send(PrepareRequestUserAuthorization()) but that seems to start the OAuth authorization from the beginning. I also tried calling WebConsumer.ProcessUserAuthorization() but that just returns null. And, to be quite frank, the documentation around DotNetOpenAuth isn't specific enough for this newb to determine what exactly these methods are supposed to do anyway. So, any help would be much appreciated.
What this app marketplace is proposing is not standard OAuth 1.0(a), and therefore not something that DotNetOpenAuth supports. That said, you could play a few tricks to make it work. Calling WebConsumer.ProcessUserAuthorization(HttpRequestInfo) with a carefully crafted argument would "fool" DotNetOpenAuth into proceeding from the point this app marketplace leaves you. You would need to craft the HttpRequestInfo object such that it contains all the message parts that would be included in a normal OAuth flow when the request token has been authorized:
oauth_token
oauth_verifier (if this is an OAuth 1.0a flow)
In addition, you'd need to artificially inject the request token and its secret into your instance of the token manager in WebConsumer.TokenManager. This also may not be trivial, depending on how you're implementing it.
I would caution you though, that whenever you depart from the standard OAuth flow, thorough security reviews are critical, because you may be defeating security mechanisms built into the protocol.

Categories

Resources