Can you run an asp.net MVC web app inside an iframe? - asp.net-mvc

My company has an asp.net mvc app that they want to run inside another webapp (probably React right now). If I just put the app inside an iframe( no react, just a static html page). It will render the inital page ok, but the first partial control fails because it cannot find the session keys.
public virtual UserModel LoggedInUser
{
get
{
return Session[SessionKeys.LOGGED_IN_USER] as UserModel; //THIS FAILS. No keys in the session
}
set
{
Session[SessionKeys.LOGGED_IN_USER] = value;
}
I'm not too suprised by this, but I don't know of a workaround. I tried a cookieless session to no avail (the app didn't run even outside the iframe). Would it help if the containing webpage was another mvc app? It seems the only option is to port all the razor pages over to react and refactor the controllers to not return view.
Any help is appreciated.

you may publish your application in another domain. thereby, you can serve it in the iframe. If you want to match with these two applications to use login, session, etc. then you can use Uniqidentifier in your query string so your MVC application would know which user sent the request

Related

External authentication in ASP.NET core Web API and Angular Client

I have an angular application that uses asp.net core Web API. I need to add external authentication for google and facebook sign in so that my web and mobile application can use this web api to authenticate users. I have gone through the documents and tutorials provided for this
like
this one and also this
but none of them are helping me because my web application is on Angular 5.
My actual problem is how to get URL that redirects me to Google or facebook sign in page.
Mostly all of them use scafolded Asp.net mvc application where there is a controller: AccountController with Methods ExternalLogins
GET /api/Account/ExternalLogins?returnUrl=%2F&generateState=true
and they say the response will be a json like this:
[{"name":"Facebook",
"url":"/api/Account/ExternalLogin?provider=Facebook&response_type=token&client_id=self&redirect_uri=http%3A%2F%2Flocalhost%3A15359%2F&state=QotufgXRptkAfJvcthIOWBnGZydgVkZWsx8YrQepeDk1",
"state":"QotufgXRptkAfJvcthIOWBnGZydgVkZWsx8YrQepeDk1"}]
This JSON is exactly what I need because i need a URL like that to open facebook or google login page. The links above use scaffolded projects and every code written there already that works great for Asp.net web application. But in my case, I have started the web api from scratch and my web application is Angular 5. Also if I tried a scafolded web api project but I could not find any controller called AccountController, nor any Method called ExternalLogins to get the JSON that contains provider name and login page url. It looks like the way its done has been changed in .net core 2.
The first link above has shown two ways to include GoogleAuthentication in startup class file for Asp.net core 1 and Asp.net Core 2. So there must be something I am missing.
I am using Asp.net core 2.
I have already got Api keys and secrets and added to startup class file.
I hope I am clear enough.
Please tell me if I need to elaborate more.
Please help. Thanks.
You need to create Challenge for Google Authentication in one of your Controller in API and redirect from angular app to that API Controller.
Controller Method
[HttpGet("ExternalLogin")]
public IActionResult ExternalLogin(string provider)
{
if (provider == null)
{
return null;
}
var properties = new AuthenticationProperties { RedirectUri = "www.mydomain.com/api/auth/callback" };
var response = Challenge(properties, provider);
return response;
}
component method called on click of google sign in button
externalLogin(provider:string){
this.document.location.href = this.baseAPIUrl + 'auth/externallogin?provider='+provider;
}

Asp.net MVC Pass onetime authentication to controller through Url.Action()

Background
I have an ASP.net MVC 4 web application with Forms authentication and a custom AuthorizeAttribute controlling access to all controllers minus the login screen. I am adding to some of the controllers, an action that allows the user to download a server generated PDF whose content and layout is being defined in a Razor View.
To carry out the conversion between Html and PDF, im using a trial version of ABCPdf9 and the bulk of the conversion works perfectly with all CSS, Text, static images, etc being displayed as required.
The problem is that I have images in the HTML that must also be rendered into the PDF file, but these images come from a controller which requires authentication.
Since the Html to PDF conversion takes place in ABCPdf using the Gecko engine, the existing user authentication cookies, etc are not available and as such the GET requests to the Image Controller are not authenticated and will not return anything. (This is the problem).
What I've discovered
From the research I have done, I came across the HttpAdditionalHeaders Property of ABCPdf which (from my understanding) is there to allow you to set header cookies, etc that will be sent with the requests made by the Gecko engine when fetching resources.
I have spent a good few hours trying to set the existing cookies from the originating request and pass them through to ABCPdf but this does not appear to work. Nor does creating a new set of authenticated cookies and pass them either.
So from what I gather, this solution is not possible....
My question
Does anyone know if it is possible to modify the Url.Action helper so it will generate and include a one-time authentication key in the url? Then implement some code in my custom AuthorizeAttribute that strip the key parameter and if valid, provide an alternative method of authentication to access the necessary image controller. This way, I can run the ABCPdf conversion process and it will be able to access the normally restricted resources in the image controller.
For example:
<img src="http://somesite.com/Image/Retrieve/1234?key=WFD6312DFV154WHSF3B1SGB69SB" />
The custom AuthorizeAttribute code should then recognise the key parameter passed in the requests query string and then bypass existing authentication processes.
Any help or even suggestions for where to look would be greatly appreciated!

How to secure a JsonResult?

The very first part of this answer on another question explains how an existing MVC site can very quickly have added to it the ability to expose its data (e.g. to a Winforms app requesting the data), all for a couple of lines of code (without having to convert to WCF/Web API and add extra layers - our project is pretty small and basic):
public JsonResult GetCategoryList()
{
var list = //return list
return Json(list, JsonRequestBehavior.AllowGet);
}
So we've tested the above as a quick and easy solution and it's clearly very nearly working because in the stream we get the html source for our MVC app's login.
And indeed if we add the AllowAnonymous annotation we do get the Json stream that we're after.
However we don't want to allow anonymous, we want some protection. Have tried adding:
Dim nc As New NetworkCredential("username", "password")
request.Credentials = nc
just before firing request.GetResponse but that isn't working (this may be completely ignorant but it seemed worth a shot). When I say it isn't working, I mean we go back to getting the login page's html source in the stream.
So how to allow the winforms app to incude some kind of authentication (which will work) with its request for the data? As I say, getting the data is working (proved by AllowAnonymous).
You should separate the authentication code for the web application (the one returning the login) from the one that you are exposing the API.
Looks like you are using forms authentication for the WebSite part and you should keep it that way. However, in the public API GetCategoryList you should either implement a different authentication strategy with ActionFilters for example.

ASP.net MVC - authentication cookie and redirects

I am looking for a bit of a point in the right direction...
We have an MVC site, with a variety of virtual directories that all point at the same code, e.g.
https://www.x.com/dir1
https://www.x.com/dir2
The different virtual directories are used partly for business reasons due to the URL 'content' and partly to control how the site is skinned.
The sites are locked down for access using forms authentication, and I am trying to track down a slightly elusive issue.
A user logs into the site using the url 'dir1', authenticates fine, SetAuthCookie is called.
We have code that runs on OnActionExecuting throughout the site - it takes the logged in user and determines which virtual directory they should be accessing (one per user) and if they are in the wrong URL, will redirect them, e.g. (simplified code):
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (Authenticated && UserIsNotInCorrectDirectory())
{
filterContext.Result = new RedirectResult("https://www.x.com/dir2");
}
}
The problem I am having is this - if I start a fresh browser (using firefox at the minute, to view the cookies) and do the following:
Log into the site using the 'dir1' url.
I get authenticated fine - I can see the set-cookie http header containing our auth cookie. This response will also redirect me to 'dir2'.
On the subsequent page, when I view the cookies, the auth cookie is not there - this is the problem.
To add to my confusion, if I then bring up the login page again (same browser, session not closed), and try this again, it works. Anybody got a clue?
My bet is that your OnActionExecuting filter is getting in the way of your login form and your session cookie is getting lost when you overwrite the result. In case this code resides in an attribute, I would try removing the attribute from your Login action and see if that works.

MVC3 mixed forms and Windows authentication

I currently have an intranet site that is accessed by external customers. I therefore set this up using Forms Authentication. However the powers that be (my bosses) want all our domain users to not have to enter their username and password to access the site.
I've done a bit or reading and everything seems to point to setting up a WinLogin.aspx page that you alter to use WindowAuthenthication and then redirect from there.
I have a problem with this as I don't like the idea of putting an aspx form in my mvc application.
Can anyone tell me how to achieve mixed authentication using a strictly MVC Controller/Action setup without a second application?
NOTES: running MVC 3 on an IIS 7 box.
Forms Authentication is not related to the URL or physical structure of your files. What matters is that a URL should ultimately map to a physical (or virtual) resource on the server, and be processed, and be returned back to the user.
Thus, somewhere in between for each incoming call (each HTTP request, even those for CSS and JavaScript files), you have to see if the current user has enough permission to access it or not. If no, then you might redirect him to the login page.
If you want, you can have a URL like /user/windowslogin where user is the name of the controller, and windowslogin is the name of your action method. Then you can create a custom authentication attribute (something like [WindowsAuthentication]) on your windowslogin action, and in that attribute (which is an MVC filter in essence), you can see if the current request comes from within your domain, and if so, talk to Active Directory for authentication or stuff like that, and on case of successful authentication, create an authentication cookie using FormsAuthentication class, and the rest of the story.
However, I don't think this would be an easy task. Others might introduce better solutions.

Resources