We're thinking about an architecture for our next app and we're having problems with pass the tokens between apis. We'll have:
Front -->(call to) own login api (if all is ok we create an own token, named ownToken) -->(call to) third party api --> returns a JWT token (named 1token) -->
After everything is ok :
Front --> User do some tasks-->(With ownToken Call to) own business api (If ownToken is ok, do some stuffs)--> (with the 1token Call to) third party api (return some stuffs) --> Show information to the user.
We want to avoid calling the third party api every time that we want information from that api, but also we don't want to show that JWT to the user (I mean localstorage,sessionstorage...).
For more information, we'll use c# language and sql server as database.
Our question:
How do you mantain 1token between APIs?
you have two different things which need to be managed:
JWT-secured calls between your front-end and your back-end
JWT-secured calls between your back-end and a 3rd party.
What I would do is simply generate a 'sessionId' in the back-end which is part of the token you send to your front end. this could be an int or guid or whatever.
I would then associate this 'sessionId' with the token retrieved from the 3rd party and store that somehow - some form of database or file storage (DB would be the obvious thing to use).
That way whenever a request comes in from your front end in your back-end code you should:
Extract sessionId from the token they provide
lookup the entry for this Id in your database to get the token associated with it
use this token to make whatever calls are required and respond
You'd have to make sure to update this association whenever you need to get new tokens, but that shouldn't be too hard.
You could also use this to make the nature of the thing a bit more async - you could return immediately to your front end with a response suggesting it's 'Working On It' then the front end could call a separate endpoint later to get the results... That way if the 3rd party link takes a while then the original request isn't left waiting too long for a response...
Related
I am working on one MVC application, where there is separate WEB API project also.
Now I want to implement update email functionality based on OTP verification from mobile via WEB API.
Web API is stateless but still, I want to implement SESSION in my code so that I can access OTP value in subsequence request and validate it. Currently, I am able to store OTP in session in the first request but in next request Session is null and I can not access stored OTP value.
I do not want database trip to store and retrieve the OTP.
public HttpResponseMessage SendOtpOnMobile([FromBody]OtpOnMobileAPIRequest objOtpOnMobileAPIRequest)
{
otpValue = CommonUtility.GenerateRandomOTP(4);
HttpContext.Current.Session["otpGeneratedValue"] = otpValue;
//Send OTP logic and response code
....
}
public HttpResponseMessage ValidateOtpFromMobile([FromBody]ValidateOtpFromMobileAPIRequest objValidateOtpFromMobileAPIRequest)
{
var otpGeneratedValue = HttpContext.Current.Session["otpGeneratedValue"];
if(objValidateOtpFromMobileAPIRequest.OTP == otpGeneratedValue)
{
//success
}
....
}
I have tried following URLs.
ASP.NET Web API session or something?
Accessing Session Using ASP.NET Web API
What you want to do and what is achievable are two different things.
Each call to the API will be discrete and won't keep track of previous requests. However, since you have an MVC app as well, I suggest you maintain the session there and simply pass whatever you want to the API as a parameter, for example.
So, return the OTP code you generated to your MVC app, if you can, and store it in session there then on subsequent API requests, pass it through from your web app.
It would help if you described the flow of your application, as suggestions will be based on that.
If you have multiple clients using your API, then each one of them will have to either maintain data required to function properly, or you will need to do that extra database trip. It's up to you which solution works better for your specific scenario.
Thats great you know "API's are stateless". I am completely agree with the words of Andrei
What you want to do and what is achievable are two different things.
If you dont want to store the OTP in your database then why dont you pass OTP in HttpRequestHeader.
Pass the OTP in your header (Preferred encrypted OTP and then decrypt it in your WEB API.
Suggesting this way as per your needs
I'm developing a jQuery website that will display a single record from my Azure Table Storage (ATS) account. I don't want to use jQuery to directly access the table, since that would require disclosure of my ATS account name and key in the jQuery code. I've tried to find a simple C# web service example project that would be the interface, but everything I can find is much more complicated than I need.
This web service will need just one API that jQuery will use: it will be passed two strings: the Partition Key and the Row Key for ATS, which will exactly match with an existing record in ATS. The result returned will be a string that jQuery will convert using JSON.parse() after it is received. If no record is found with the Partition and Row Keys passed in, an empty string should be returned.
If you know of an example of a simple C# web service that I could use as a starting point, I would greatly appreciate a link to it. It's been many years since I developed with C#, and the complicated nature of the table service API with all the associated crypto, hashing, signatures, etc. have left me confused.
Edit: I now realize that maybe both my jQuery code (providing the web UI) and the C# (providing the ATS interface) might work together in one .NET solution. I'm currently running the jQuery UI app standalone in its own .NET solution, due to my path of fumbling around trying things out.
I don't want to use jQuery to directly access the table, since that would require disclosure of my ATS account name and key in the jQuery code.
It seems that you do not want jQuery client directly make a GET request to query entity via table service Rest API, and you’d like to create a backend service for querying entity in table. As maccettura mentioned in comment, you can create a ASP.NET Web API project and do Query Entities operation in controller action.
[Route("queryentity/{pk}/{rk}")]
public CustomerEntity Get(string pk, string rk)
{
//you can install [Azure Storage Client Library for .NET](https://www.nuget.org/packages/WindowsAzure.Storage/)
//and then create a retrieve operation and pass both partition and row keys to retrieve a single entity
//TableOperation retrieveOperation = TableOperation.Retrieve<CustomerEntity>(pk, rk);
//or
//make [Query Entities](https://learn.microsoft.com/en-us/rest/api/storageservices/query-entities) operation as you did
return myCustomerEntity;
}
Let's assume we have a RESTful web service that will calculate UK Royal Mail postage charges.
There would be a number of essential input parameters:
weight of item (grams, int),
length of item (cm, int),
width of item (cm, int),
category of item (letter/parcel, string/enum),
service required (first class/second class/special delivery/etc, string/enum),
destination (domestic/international/maybe further specify the latter, string/enum)
Such an application would be easy to create as a WebAPI. It could be called via a URL such as ...
http://myserver.com/api/mailcharges?weight=150&length=15&width=10&category=letter&service=first&destination=domestic
The web service would then do a simple lookup on its internal tables and return the postage in its response payload.
The beauty of this is that it could then be utilised by a variety of applications within an organisation (or even outside it!). However, this requires that each application that calls the web service needs to be able to populate these parameters; the integers are OK, they are just that - numbers. But the strings or enums are more difficult. The logic for entering and validating these needs to be replicated in every client application. Wouldn't it be nicer if the web service could prompt the user for any which are not passed in or passed as nulls or invalid values. In fact wouldn't it be nicer still if the web service had a user interface which allowed a user to enter any or all of the parameters.
What I am looking for is a cross between a web site and a web service. A web application which can be called via a simple RESTful http request, which pops up a user dialogue, accepts user input, and when the user clicks on a suitable button, does its calculation and returns its answers as a JSON/XML response.
Does anyone have any ideas on how to implement such an architecture? I have tried calling MVC actions/views from within a web api controller but the response is the html for the MVC view, and is returned to the api controller directly rather than being rendered and POSTing back its user input.
I hope I am just being thick, and that the answer is obvious, but all my experiments have so far failed, and any suggestions, no matter how far fetched or outrageous, would be very welcome.
I realize that this is a fairly trivial example, but the same argument goes for much more complicated web services where the replication of user input forms, input validation, complex processing logic etc. across multiple client applications would be far more of an issue than with this example.
if the web service could prompt the user is essentially missing the point of a service. It is no longer a webservice, but a webpage.
In order for internal/external applications/websites to utilize your service, they essentially need to know three things:
where to ask - this is your http://myserver.com/api/mailcharges
what are the arguments - that is weight, length…
what are accepted argument values
While 1. and 2. are usually mere API documentation you seem to have a problem with p. 3 - you want the user to be somehow prompted to choose among possible values and not guess. But you also want the user application not to be responsible for maintaining/validating the list of possible values.
Guess what? You simply need another API. :) An API to describe your arguments.
Let's concentrate on category field. Your API could be extended with a new URL: http://myserver.com/api/getCategories which essentially returns a list of available (currently understood by API) possible category values. This can be JSON, or comma separated string or whatever reliable. Now your end-user GUI-enabled application calls the API, asks for categories, and creates UI accordingly - populating ComboBox or whatever with obtained values. The same is done for other fields. You can. i.e. obtain acceptable ranges of weight or length.
The important thing you mention in your question is validation: logic for entering and validating these needs to be replicated in every client application. This is somehow true, as it essentially depends on the technology used in the end-user application. On the other hand it is very important, that the API performs validation itself! You can never know who is going to use your API. And it is always better to check twice then never.
On an existing host I've added Web API Models & Controllers. I've added the following four:
Products
Orders
Categories
Users
When someone accesses the localhost:port\api\products, it returns all the products in JSON format.
The Create, Update and Delete statements are completely disabled, so we are only able to use GET-requests on the API (so either \api\products for a list of all products or api\products\# for a single products with id #).
Because the other CRUD's aren't used, there isn't a lot of security that should be added to the Web API, except for one thing: The Users
These will also return emails and such, which would be better to keep private and unreadable without the proper authorization (without entire log-in pages, but a way to authenticate yourself when accessing the Web API in for example Android HttpGetRequests).
So, the question: How should I add authorization for only the UsersController accessed by the Web API.
And, how can I encrypt the JSON in C# and decrypt it in Android again. If this second part is too big to answer I'll make a new question later on, my main focus is the low-end [<- without log-in pages, so built in into the GET-request] authorization of the Web API's GET-request for Users.
Edit 1: I did found this link where a new project is made with Authorization Changed to Individual Users. I also see that the user is registered and then logged in with POST and GET requests.
The following questions came into mind when reading through this link:
How to change the Web API's Authorization to Individual Users on an existing project?
Our authorization is done through OAuth (mainly Google-account) with our work e-mail address. I guess it's not possible / easy to authorize in the same way as in the link with a Google-account on Web API GET-requests.
Edit 2: After using the first link provided by Vladimir Gondarev I've added the [Authorize] to both the Get methods in the UsersController. In my project everything else was already used before, like a class that uses the AuthorizeAttribute, so just adding the [Authorize] was already enough for the first step. Now in the browser I get an unauthorized (JSON) back when I'm not logged in, which is good.
The next step would be to add the OAuth-authorization to the Android app, but that is an entire new problem / question that I will look into first before asking a new stackoverflow-question.
The simplest solution would be "Basic Authentification". In order to to implement it you have to derive from AuthorizeAttribute and then apply it to a method or a controller.
Here you find further info:
What is basic Authentification:
http://www.asp.net/web-api/overview/security/basic-authentication
Implementation:
ASP.net Web API RESTful web service + Basic authentication
You don't have to encrypt anything as long as you use HTTPS transport.
My applciation works as follows
[user]----username/password/domain----->[WCF service]
then i access the domain server to see to which actual DB the user is associated,
after getting that, i validate the user in his actual DB(DB is per domain)
the problem is that i need a place to store the domain name for the following requests against the db.
for example,if the users calls a WCF service operation:
Test()
first the validation procedure is called, (WCF UserNamePasswordValidator) which validates the user password(which is sent as part of the header for REST or as part of the SOAP), and the next function to be called is the Test, but by then i cant tell the domain of the user(to actually serve the request agains that domain..)
I dont want to change the signature of each domain to
Test(string domain)
I cant simply access the headers since i expose the same methods both as REST and as SOAP and the authentication is different for each of them..(one is with headers as with Amazon S3 and the later is using the SOAP standard)
so basically i'm looking for a global, per call storage.(i want to avoid the Per-Call initiation method)
thanks.
EDIT:
Maybe i should use the ThreadStaticAttribute? will that work?
This will not work. You can't store anything in UserNamePasswordValidator. It even doesn't have access to OperationContext because it runs on different thread.
The way to do this is create custom message inspector and extract the information from custom message header to custom operation context extension as Frank mentioned.
WCF knows a Current OperationContext. You can write your own extensions for it. Unrelated to this issue, I used the same mechanics in this NHibernate Session management here, which may work in its concept for you as well. It accesses the InstanceContext, but the concepts are similar.