Create another Logon page for external link - asp.net-mvc

I want to create another logon page for external direct link(multiple projects need identity Logon page appearance.)
Is that possible to create another view for logon controller or I need to create another controller? I tried to create another controller, but I can not access at all.
Is there someone get some good ideas about that??
Cheers

If you are using same authentication mechanism, you can just pass external URL as parameter
http://yourwebsite/Account/LogOn?returnUrl=<external url>
and then redirect the page to the return URL after authentication.

It's a bad idea for your logon to return to an external link. don't do that. See Ch7 of the Wrox Professional ASP.NET MVC 3 book.
This is known as an open redirect attack. There's code in ASP.NET MVC 3 internet template for the Account Controller which prevents Open Redirect, but the risk of allowing it is that anybody can give out links to your site's login address with a malicious url in the return url query string. By allowing this Open Redirect, you make your site's visitors prone to social engineering. A hacker could send out links to your site to your users. They click, it looks like your site, address bar is right, the site appears secure, cert good and all. They logon, then they're redirected by your site to an external url. The external url may have any code running at all, and could make your users vulnerable to any number of attacks/ javascript attacks.
I know I mention MVC in particular, but the same holds true for any site.
If you need a logon page for another site, then you need to copy in the controller and views to that project, as well as setting up the config in that project (you can view your existing project for the appropriate settings).
Are your sites all related, with the same users and such? or are they separate disparate sites? If they are all related, can you put them in one project? That way you could just use the one membership provider and db, and different controllers/view folders for the different sections of your site?
Or are you in a domain where you can use Windows Auth and skip showing a logon page?
Or do you want to go with a single sign on application like ACS in Azure or STS server, or something. (look for good/modern book on WIF, which discusses ACS 2.0, if so)

Related

Is it possible to use authenticatedUserOverride in IIS and still get the windows user within an MVC application?

We're trying to setup IIS so that is uses its IIS AppPool identity when going against ACL permission checks (when getting static files from the filesystem) so that we don't have to add "everyone" or "authenticated" users to the main app folder or specific folders.
We've found that setting authenticatedUserOverride to UserWorkerProcessUser achieves the above, but no longer lets us access the specific windows user hitting the website from within the MVC application.
Is there a better way to accomplish this? Again, we're trying avoid having the specific user's credentials validated against ACLs when accessing files.
You can still get the authenticated user that is accessing the site using the LOGON_USER in the Request:
Request["LOGON_USER"]
Scott Forsyth details this on his blog under option #4 (http://weblogs.asp.net/owscott/iis-using-windows-authentication-with-minimal-permissions-granted-to-disk).
As for the best way to accomplish this, I think you are on the right path. I have used this approach along with the roles authorization aspect of ASP.NET to allow/deny access based on membership.

Method for Sharing Forms Authentication Login between MVC.net and Web API Sites on the Same Domain

I am going to have an ASP.net MVC web site (example.com) and a Web API site (api.example.com) running on the same domain. What is the best and most secure way to use Forms Authentication to allow a user to log in to the MVC site, and have that login accepted by the [Authorize] filter in the API site? Additionally, there is the possibility that both sites will be hosted on multiple servers (each of which might have its own subdomain), so a solution that would allow for a single sign on approach to work among all of the servers in the cluster would be preferred.
Take a look at this link http://www.codeproject.com/Articles/27576/Single-Sign-on-in-ASP-NET-and-Other-Platforms this covers the answer in detail.
You will need to ensure all machines and separate applications on the site share a common (but unique to production) machine key to allow the authentication cookies to be trusted by all the machines/applications.
If you are simply using virtual directories under the same sub domain then simply harmonising the web.conig Forms Auth settings and machine keys should get you up and running very quickly.
If you want this to work between a second level domain then you need to change the "Domain" setting on the Form's Auth cookie. See the article for details.

Http handler for classic ASP application for introducing a layer between client and server

I've a huge classic ASP application where in thousands of users manage their company/business data. Currently this is not multi-user so that application users can create users and authorize them to access certain areas in the system.
I'm thinking of writing a handler which will act as middle man between client and server and go through every request and find out who the user is and whether he is authorized to access the data he is trying to.
For the moment ignore about the part how I'm going to check the authorization and all that stuff. Just want to know whether I can implement a ASP.net handler and use it as middle man for the requests coming for a asp website? I just want to read the url and see what is the page user is trying to access and what are the parameters he is passing in the url the posted data. Is this possible? I read that Asp.net handler cannot be used with asp website and I need to use isapi filter or extensions for that and that can be developed only c/c++.
Can anybody through some light on this and guide me whether I'm in the right direction or not?
Note: To be specific, I cannot modify anything in the existing application because there are hundreds of pages (each page again has couple of different actions, such as posted to the same page again) are there in the system and it is really big mess and we are coming up with a different solution to clear that mess but that takes couple of years to complete, meanwhile to provide the multi-user functionality to the users we are trying to do this. This layer acts like layer where we authorize the user to do certain operation or access a page, nothing more than this.
I've worked with an ASP classic website that runs Javascript on the server side. In IIS we selected JScript as the server-side scripting language and access the session variables and the database simultaneously to check user's access rights when they try to check out various parts of the site. What you're describing is completely do-able. Each page needs to have Javascript in <% %> tags and that identifies the content as server-side code. Be careful with security though!
As for the ASP.NET handler, I also developed an ASP.NET application that I added imported to our site (had to use a .NET thread pool) which could handle Ajax requests. IIS has this option to import ASP.NET applications to your site.
You've got options.

ASP.NET MVC 2 and authentication using WIF (Windows Identity Foundation)

Are there any decent examples of the following available:
Looking through the WIF SDK, there are examples of using WIF in conjunction with ASP.NET using the WSFederationAuthenticationModule (FAM) to redirect to an ASP.NET site thin skin on top of a Security Token Service (STS) that user uses to authenticate (via supplying a username and password).
If I understand WIF and claims-based access correctly, I would like my application to provide its own login screen where users provide their username and password and let this delegate to an STS for authentication, sending the login details to an endpoint via a security standard (WS-*), and expecting a SAML token to be returned. Ideally, the SessionAuthenticationModule would work as per the examples using FAM in conjunction with SessionAuthenticationModule i.e. be responsible for reconstructing the IClaimsPrincipal from the session security chunked cookie and redirecting to my application login page when the security session expires.
Is what I describe possible using FAM and SessionAuthenticationModule with appropriate web.config settings, or do I need to think about writing a HttpModule myself to handle this? Alternatively, is redirecting to a thin web site STS where users log in the de facto approach in a passive requestor scenario?
An example of WIF + MVC is available in this chapter of the "Claims Identity Guide":
http://msdn.microsoft.com/en-us/library/ff359105.aspx
I do suggest reading the first couple chapters to understand all underlying principles. This blog post covers the specifics of MVC + WIF:
Link
Controlling the login experience is perfectly fine. You should just deploy your own STS (in your domain, with your look & feel, etc). Your apps would simply rely on it for AuthN (that's why a app is usually called a "relying party").
The advantage of the architecture is that authN is delegated to 1 component (the STS) and not spread out throughout many apps. But the other (huge) advantage is that you can enable more sophisticated scenarios very easily. For example you can now federate with other organization's identity providers.
Hope it helps
Eugenio
#RisingStar:
The token (containing the claims) can be optionally encrypted (otherwise they will be in clear text). That's why SSL is always recommended for interactions between the browser and the STS.
Notice that even though they are in clear text, tampering is not possible because the token is digitally signed.
That's an interesting question you've asked. I know that for whatever reason, Microsoft put out this "Windows Identity Foundation" framework without much documentation. I know this because I've been tasked with figuring out how to use it with a new project and integrating it with existing infrastructure. I've been searching the web for months looking for good information.
I've taken a somewhat different angle to solving the problem you describe.
I took an existing log-on application and integrated Microsoft's WIF plumbing into it. By that, I mean that I have an application where a user logs in. The log-on application submits the credentials supplied by the user to another server which returns the users identity (or indicates log-on failure).
Looking at some of Microsoft's examples, I see that they do the following:
Construct a SignInRequestMessage from a querystring (generated by a relying party application), construct a security token service from a custom class, and finally call FederatedSecurityTokenServiceOperations.ProcessSignInresponse with the current httpcontext.response. Unfortunately, I can't really explain it well here; you really need to look at the code samples.
Some of my code is very similar to the code sample. Where you're going to be interested in implementing a lot of your own logic is in the GetOutputClaimsIdentity. This is the function that constructs the claims-identity that describes the logged-in user.
Now, here's what I think you're really interested in knowing. This is what Microsoft doesn't tell you in their documentation, AFAIK.
Once the user logs in, they are redirected back to the relying party application. Regardless of how the log-on application works, the WIF classes will send a response to the user's browser that contains a "hidden" HTML input that contains the token signing certificate and the user's claims. (The claims will be in clear text). At the end of this response is a redirect to your relying-party website. I only know about this action because I captured it with "Fiddler"
Once back at the relying party web site, the WIF classes will handle the response (before any of your code is run). The certificate will be validated. By default, if you've set up your relying party web site with FedUtil.exe (by clicking "Add STS Reference in your relying party application from Visual Studio), Microsoft's class will verify the certificate thumbprint.
Finally, the WIF framework sets cookies in the user's browser (In my experience, the cookie names start out with "FedAuth") that contain the users claims. The cookies are not human readable.
Once that happens, you may optionally perform operations on the user's claims within the relying party website using the ClaimsAuthenticationClass. This is where your code is running again.
I know this is different from what you describe, but I have this setup working. I hope this helps!
ps. Please check out the other questions I've asked about Windows Identity Foundation.
UPDATE: To answer question in comment below:
One thing that I left out is that redirection to the STS log-on application happens by way of a redirect with a query-string containing the URL of the application the user is logging in to. This redirect happens automatically the first time a user tries to access a page that requires authentication. Alternatively, I believe that you could do the redirect manually with the WSFederationAuthentication module.
I've never tried to do this, but if you want to use a log-on page within the application itself, I believe the framework should allow you to use the following:
1) Encapsulate your STS code within a library.
2) Reference the library from your application.
3) Create a log-on page within your application. Make sure that such page does not require authentication.
4) Set the issuer property of the wsFederation element within the Microsoft.IdentityModel section of your web.config to the login page.
What you want to do is an active signin. WIF includes WSTrustChannel(Factory) which allows you to communicate directly with the STS and obtain a security token. If you want your login form to work this way, you can follow the "WSTrustChannel" sample from the WIF 4.0 SDK. Once you have obtained the token, the following code will take that token and call the WIF handler to create a session token and set the appropriate cookie:
public void EstablishAuthSession(GenericXmlSecurityToken genericToken)
{
var handlers = FederatedAuthentication.ServiceConfiguration.SecurityTokenHandlers;
var token = handlers.ReadToken(new XmlTextReader(
new StringReader(genericToken.TokenXml.OuterXml)));
var identity = handlers.ValidateToken(token).First();
// create session token
var sessionToken = new SessionSecurityToken(
ClaimsPrincipal.CreateFromIdentity(identity));
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken);
}
Once you have done this, your site ought to behave the same as if passive signing had occurred.
You could use the FederatedPassiveSignIn Control.
Setting your cookie like this:
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken);
Doens't work for SSO to other domains.
To cookie should be set by the STS not at the RP.

Securing a mvc view so only the server can access it

I'm building a .Net MVC app, where I'm using one particular view to generate an internal report. I don't want the users of the site to gain access to this page at all.
I've a console app that fires every so often which will scrape some of the details from this page by hitting it's URL.
I don't like the idea of having the URL hanging out there but I'm not sure of another way to go about it.
Thoughts on what might be the best practice way for tackling this?
Edit:
Here's what I ended up doing, created a new WCF Service project in the solution. I also copied basically what was the MVC view page into a new standard web forms page in this project. On top of adding security via the regular .net Authentication methods (eg set only valid windows users can access the page), I can also lock down the vhost to only be accessed by certain IP's.
The best practice would be to expose a wcf service for this, and set up a security model that is different than website.
If you must use MVC the best approach use forms authentication with mvc and set
[Authorize(Roles = "SecureUser")]
On the View.
If the view never needs to be rendered at all except to provide data for the console app, then why not have the console app simply connect to your database to get the data directly instead of going through the web app? You could still do this for the console app even if the view does need to be available for some users, then control access to the view using the Authorization attribute, which could suitably restricted now that an external app need not have access to it.

Resources