Web API how to secure token when using IFrame on clientside - c#

I have a ASP.NET Web API server application and Javascript frontend.
The way Im implementing authentication is by using a Token that is sent and received in the HTTP Response Headers.
When the users log into the application, my server will send back to the client a JSON object with a session Token. The javascript client then stores that in a browser cookie.
Every call that the javascript client makes to the server, the token is sent in to a custom header so the server can decrypt that and validate it in the database so it know if its a valid session.
Everything works great here, If I need to secure that part then adding a SSL will help.
Now, there are calls in the app that I need to use an IFrame so I set the src property to the web api method I need to call.
It's not possible to add a custom HTTP Header when using IFrame, just a simple URL into src property
Of course using this there is no way to send a custom header so what I did was to append a parameter into the scr url like this:
<iframe scr="/api/report/GenerateReport?sessionUid=" + getCookie('sessionuid') ></iframe>
This is my web api method that receives the sessionUid as a parameter.
[HttpGet]
public HttpResponseMessage GenerateReport(string sessionUid) {
// validates session
bool validSession = common.ValidateSession(sessionUid);
if (validSession) {
// do some stuff here
}
}
My question is... how can I secure my token, because if someone steals the sessionuid he then can call all the HttpGet methods that receives sessionUid as a parameter?
Any clue?

If your website is not using SSL, then you cannot 100% secure the communication between your website and user's browser.
Attackers usually hijack you whole HTTP package, including HTTP headers, put session in HTTP header is not enough for security.

The answer to your specific question is to encrypt the querystring parameters.

Related

Clarify how cookies are working between Angular and c# controller

I would like to clarify how cookies work between angular app and the c# server controller.
This is what I gathered from various discussions and forums:
The angular client sends HTTP Request (e.g. to login) to the c# server
c# server creates the cookie (e.g. refreshToken) using:
Response.Cookies.Append("refreshToken", token, cookieOptions);
c# server returns and the cookie refreshToken is set in store on the client side
Whenever the angular client sends the HTTP request again, the cookie is set in the Request object (probably by the browser, behind the scenes - angular client does not explicitly set the cookie)
c# server receives the request and retrieves the cookie like below:
var refreshToken = Request.Cookies["refreshToken"];
Is my understanding correct?
Yes, your understanding is totally correct.
One note: Angular HttpClient does only include cookies for cross-domain requests (like in dev environment) in the request if HttpOption withCredentials is set to true.

Redirect to a page with api response in ASP.NET Core MVC

I have an api controller with a http GET method. This method is invoked from a frontend. In response to this, I want to redirect user to dashboard page and also provide some login response object. When a request comes into this method, it comes from a different page.
The request comes to this method with a path api/accounts/loginobject when a third party identity servers sends oauth2 authentication. This is a redirect url method.
[HttpGet]
[Route("LoginObject")]
public async Task<IActionResult> getLoginObject()
{
var externalLoginInfo = await this.signInManager.GetExternalLoginInfoAsync().ConfigureAwait(false);
// parse token here
}
I tried below code and it works. But I don't know if we can send response object in the below response. I want to attach token in the headers and some info in the response body.
// dashboard is a ui page not another controller action
return Redirect("/dashboard");
The front end app is an angular app part of ASP.NET Core MVC project. I have a third party identity server which sends oauth2 result back to this controller.
The following will set header but it will be lost when the redirection to html page /dashboard happens. Still I am not able to respond to ui with access token
this.Response.Headers.Add("Authorization", $"Bearer {accessToken}");
Update:
I solved this temporarily by passing token in query string. It looks more like a hack for now. Once received it in ui, i will set it in web app local storage for subsequent api calls.
https://mywebsite/accesstokencallback?access_token=eybcsdfk23klsd-3dsfjs

My web browser won't store the cookie from the response header

I have an API located at http://localhost:57780.
When I attempt to call the login endpoint from my client (http://localhost:4200), I receive my cookie in the response header AND it is successfully stored in the browsers cookies.
Now, here is my issue: Using the same API, I now call the login endpoint from my client at a different DOMAIN (http://127.0.0.1:4200).
I still successfully receive my cookie in the response header ALTHOUGH the browser is not storing this cookie.
I am using the HTTP interceptor so that each call has withCredentials set to true.
I have also set Access-Control-Allow-Origin to AllowAnyOrigin.
What am I doing wrong?
P.S: This is my first stackOverflow post so any tips would be greatly appreciated :)

How to Consume WebApi WebService that Requires Redirect for Login

We have a desktop application that requires authentication with a server in order to operate. This application prepares and sends a query to a webservice, the user is prompted from this webservice to log in and the webservice returns an XML document with application subscription information (Software-as-a-Service Subscription License).
I've created a WebApi webservice that does the following:
Accept incoming request at /api/client?[MACHINEINFOINQUERYSTRING]
Redirect to external authentication provider (think GoogleId or
similar)
Authentication provider sends information back to
/api/subscription/[AUTHENTICATIONID]
The /api/subscription endpoint returns an XML document after pulling info from the servers (or including appropriate error message).
This webservice works and the XML document can be viewed in the browser. I've created a website with a default.aspx to test this, automatically redirecting to the /api/client and it does display this XML document in the browser.
The desktop application properly makes the initial call, redirects through an embedded browser to the login page, and receives an XML, but this XML cannot be parsed. The application team simply gets a "download" option for the XML but cannot capture the response for stuffing into an XmlDocument object. I've attempted to create an example application to instruct the app team, but have had no success.
Questions:
Do I have this architecture fundamentally wrong or do we simply not know how to consume the response properly?
How do I capture and consume the XML that is successfully returned?
As an example of what I've tried:
string requestString = string.Format("http://[server]/api/client?{0}", HttpUtility.HtmlEncode(queryString));
Response.Redirect(requestString);
This works in the browser, displays the login page, allows for input, redirects to the subscription endpoint which then prepares and delivers the XML to the browser. Unfortunately, this is unusable by a consumer.
HttpWebRequest request = WebRequest.Create(requestString) as HttpWebRequest;
request.AllowAutoRedirect = true;
request.MaximumAutomaticRedirections = 20;
request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.None;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
This doesn't work. The response.ResponseUri has the properly formatted address of the OAuth service (step 2 above). It does not display the login page to the user even though this is all initiated through a browser.
I've also tried using a WebRequest POST, HttpClient PostAsync and several other methods, but:
The response URL is simply the location of the login page. If I string together 3 WebRequest/WebResponse pairs, it fails because the user isn't being properly authenticated at the first request / initial redirect.
What does work in my default.aspx:
I haven't found an example online for my specific needs, but the pattern must exist in practice as plenty of websites utilize OAuth style logins. I've utilized webservices (like OData endpoints) that also require logins, so this pattern must exist for webservices too. I do send back a properly formatted XML document. We just don't know how to capture and consume that document.
Any examples of a similar architecture would be highly appreciated! Or pointing me in the right direction.
Edit ---
I'm thinking that somehow the request.GetResponse() isn't really allowing for redirects and/or since it's an HttpWebRequest, there's no way it will allow for user input.
What's the proper way to make this call and consume the XML from another application? the XML is delivered properly in a browser window (with Response.Redirect) but no login window opens using an HttpWebRequest.
The answer is: This architecture is fundamentally wrong.
OAuth architecture leaves the authorization to the client, which then sends an authorization token to all subsequent services that it requires. The services are simple endpoints and do not contain any authentication logic, (although the service itself is allowed to validate the authentication token with the OAuth server).
The proper sequence of events for this answer should be:
1) Desktop Application makes OAuth authentication request to authentication server.
2) A successful response includes an authorization token which contains identity information, permissions, validity period, etc.
3) The desktop app then requests information from the WebApi service, sending in the request that token.
4) WebApi takes this authentication token, validates it (in my case against a certificate) and may even query the OAuth server again to ensure that the token is still valid.
5) If valid, the web service gathers the data and sends it back to the server.
My problem was I was expecting the subscription service itself to be able to open a web browser, prompt for a login, and then continue the request to another endpoint (2 redirects after initial request). I was in effect, breaking both the WebApi and OAuth 2 designs. Although it worked from the browser, it was not consumable from an application.
After redesigning to this simpler pattern, my web service is now consumable.

Testing Web API functionality with Fiddler

I am developing a c# web api application. I am trying to test the /Token (login) and the ChangePassword action. I was able to simulate the /Token request and get the access_token from the response. However, I am unsure of how to use fiddler to test the ChangePassword action. If I just pass the OldPassword, NewPassword and ConfirmPassword, I get an unauthorized error, which makes sense as I have AuthorizeAttribute set as a GlobalFilter. It seems like I have to somehow pass the access_token as well. My question is how do I pass the access_token with the other fields?
I've never used Fiddler for that, but if it's a restful service I would just use Postman (free Chrome extension) or a similar restful client. In Postman you just fill out the URL, click the Headers button and fill out 2 form fields (header/value) to add the access_token to the request.
Good luck

Categories

Resources