Technology
ASP.NET, VB.NET 2.0 (soon to be 4.0)
Overview
I'm writing a Login / Authentication Portal, so that a web application can use it to login a user, and then they can use the application using their credentials.
The login portal will be a separate application, and initially only available via an extranet as well as intranet for certain applications; but future apps will need to authenticate via the web (happy to implement as a separate instance). I basically want other individual applications to be able to authenticate users via this portal.
So that...
A user goes to an application's web url (i.e. www.application.com / http://apps/application - intranet) and clicks "login".
User's browser is redirected to the portal application, with a query
string
www.loginportal.com/login.aspx?url=www.application.com/login.aspx
(or other page).
User fills in their credentials (username, password), and clicks
"login" button.
Browser redirects back to url i.e. www.applications.com/default.aspx or login.aspx and is authenticated and logged in; and can use app.
Completed
I have the authentication itself sorted, and will implement as a class library in the local applications via a dll.
Need
So I basically need to know, how to:-
1. Post data to the portal url (could be different domain).
2. Redirect browser with post.
3. Make sure that the authentication is secure, and not easily hackable (I know how to use urlencode and htmlencode etc) - just not sure about implications of posting data across domains.
Any help greatly appreciated...
Cheers,
Duncan.
Seriously tough stuff, here. If it were me, I'd lean heavily on Windows Identity Foundation. I believe it can support this scenario (haven't actually done it; someone else at my company is developing against it).
OK, so this is the solution I ended up using:
In the original application (the one that needs the authentication; step 1 above) I redirect the user to my login portal, and include the original url as a get parameter.
The user then types in their details, username and password.
Next, the server-side code authenticates them, and redirects to a new page, where I send back to the page an html form which includes the request datetime (for security) along with a encrypted string (including the datetime of the request) of the data I want sent back to the original form.
I also add a JavaScript post method which sends the data to the original url as a form post. Because I'm using the same class library at both ends, I can encrypt and decrypt the data using the same method and the original requesting application has all the user data, including the ability to check the datetime of the request (I allow a set amount of time between the authentication and the picking up by the original app, making sure these are within say 5 minutes.
And job done.
If anyone wants the code, I can provide it, just don't have it with me at the moment, if I remember I'll post it.
Not the most elegant solution, but it works, and it's secure, so I'm happy. :).
Related
I'm developing a web application that requires the user to log in using forms authentication. inside the webpage you need to download a desktop application that requires to login to the same system too. Is there a way to transfer the current logged credentials from the web application to the windows desktop application without need to login again?. Both applications shares a Login object from an vb.net interface.
I tried to save the IP address in the Database but that don't work for me because the website needs to be accessed inside and/or outside of the company and the user cannot login twice in different machines.
I tried to google for solutions but without luck.
Do you have any suggestions regarding this?
This may not be exactly the scenario you're envisioning, but this article shows how to use Forms authentication from a Winforms client using WCF Authentication Services. This should get you going in the right direction. Per the article, you can use these services in any .NET application.
http://msdn.microsoft.com/en-us/library/bb386582.aspx
This article shows how to do it with a Silverlight app, just so you have another example. http://blogs.msdn.com/b/brada/archive/2008/05/03/accessing-the-asp-net-authentication-profile-and-role-service-in-silverlight.aspx
And just one more for fun. http://aspalliance.com/1595_Client_Application_Services__Part_1.all#Page1
There isn't really any way to share this without encrypting a file containing the user's credentials and storing it on the hard drive along with the file, but then you run the risk of someone decrypting the information and getting access to the user's password.
I think that an alternate approach that could work is to generate an authentication token (could be as simple as a GUID) and store it in your database along with the user's id when the user requests the download. You would want this token to expire after a reasonable time limit (5 minutes, for example).
You could then include a file that contains this authentication token with the download. When your apps starts, you could check for the existence of the file. If it's there, you extract the token, delete the file, send the token prior to presenting the user login.
If the token valid, your server would send back the user's login and your app would proceed as though the user were logged in, otherwise you would just display the login screen.
I have an asp.net application in which I have used forms authentication.
Now, there is a need that user authentication is done outside of my application.
There will be an intro page which will do needed authentication.
Then, after authentication is successful user should be redirected to my app.
Of course, if user is not authenticated via that external page and tries to access my app directly, I need to redirect him back to this external log in page.
What's the best way to implement such a functionality? One way which I think is feasible is that I transfer some particular encrypted string in cookie from external login page and verify it in my application. So, based on that, I can see if user is authenticated via this external page or not.
Your own suggestion of validating the external site's cookie is how I would implement this functionality as well.
I would simply go with adding a Webservice in the first application that you in your stage can connect to a check if the user is logged in, the only problem with this is that you need to know which user whants access to your site and also to confirm that this is truly that user (So a user cant use other users who are logged in). This info could probably be sent via a cookie.
You probably should no be rolling your own single sign on solution in 2011. Rather, you should look at some emerging standards -- particularly OAuth and OpenID. Getting rolling with them is easy -- check out the OpenID website template on MSDN.
At the end we decided to use SAML 2.0 protocol.
External login page posts SAML complient XML digitally signed with certificate to other application. In this XML authenticated username is transferred. Application which receives this XML verifies digital signature with certificate's public key, and if validation is OK, reads username from XML, applies internal application authorization logic and at the end creates auth. cookie. We will probably add encryption so data protection would be complete.
Here's the situation, I've got a console application that needs to run once a day and make a few requests to pages that require authentication to view. The pages are hosted in a really basic ASP.Net Web Application.
So, I know that in order for the requests to go through successfully I have to authenticate with the server. So I've hooked up the console application to the ASP.Net Membership Provider I'm using for the web app and it successfully determines if a set of a credentials are valid. However, after calling Membership.ValidateUser() any requests I make just get the login screen. After doing some reading it seems that this is because I'm missing the important cookie information that persists my login or what-have-you.
I'm using a basic WebClient to make the requests and then reading/discarding the result.
So the meat of the question is this: Is there a simple way to validate the login information and hold on to it so that I can make the requests successfully, or is this the exact same case as the other two questions I found that require the WebClient to make a "manual" login request to the login.aspx page and try to hold on to the cookie from there?
The questions I'm referencing are:
Authenticating ASP.NET MVC user from a WPF application
and
Login to website and use cookie to get source for another page
With FormsAuthentication the webserver has to generate a Forms Authentication Ticket for you. The best (only?) way to do this is to log into the site, so I'd just log in like the other questions.
If the intent is to send data to the server and/or get data from the server, then the most logical architecture is probably to create a web service using either ASMX or WCF. Then configure the service to use a security token, such as a username token or a SAML token. This will make the client less likely to break when the server code changes its data model.
Otherwise, if you wish to use only a basic WebClient, then you will have to find a way to pass your credentials to the login page and retain the login cookie that is returned from the login request. Then, make sure that the login cookie is included on all subsequent requets, similar to the Stack Overflow question that you referenced, "Login to website and use cookie to get source for another page".
I'm not sure if I'll be clear enough in my explaination to make you guys understand, but I'll try.
Here's my problem:
We have an external site which the users in our company connect to by giving their corresponding username and password. The external site is an ASP.NET website. We want to integrate this website into our intranet portal so that the users don't have to enter their UN/Pwd to login to the website. Since the target website has no provision for SSO, we are simulating the POST request to login.
So far so good.
We are now required to perform an action after the initial login is done, on an another page. We can simulate the corresponding POST request as well. But the problem is since we are not maintaining any session information in our initial POST request, it always redirects to the login screen!
Is there any way to maintain ASP.NET session information between multiple calls done programmatically? Can we create an ASP.NET session id cookie programmatically and then pass it along with our initial request?
Or this is not possible at all?
Any comments are appreciated.
Thanks for your help.
Regards.
Maintaining the state is the responsibility of the other site (typically in a cookie).
You should perform the actions manually, then use Fiddler to compare the HTTP requests and figure out what's wrong.
I'm looking for a way to pass some sort of credentials or Authorization token from a VB.Net Client to an ASP.Net web application that allows the Client to auto-login to our Forms-Authenticated website. If a user is logged into a local application, I want them to be able to view some web pages without having to login to the website as well. The credentials are not the same between the apps, but I would just like to pass some sort of encrypted token or key to the web page so I know they are coming from the desktop application. Is this possible without requiring a username and password login?
I also need to make sure this URL that is used cannot be simply copied and used from another location, so I'll need to include some sort of information in the encrypted value to know where it's coming from.
I know how to login the user with Forms Authentication and all that, just need to figure out the best way to secure this. Thanks!
OAuth is commonly used to allow desktop applications to access a user's private data on a web site. Since you're using .NET, I suggest you check out DotNetOpenAuth which includes sample OAuth web sites and client applications. It allows for this secure token to be passed that can tell your web site that the desktop app is the one making the requests and (usually) whose data is being accessed.
The best part about the OAuth solution is your desktop app never has to ask for the user's credentials. No credentials are in the URL. And if the desktop application is ever compromised (perhaps by the computer being stolen), the web site can kill the secure token the desktop app was using to cut off access without requiring the user to change their password.
You might want to look into issuing client-side certificates for these applications. Basically, you generate a certificate that you install with the client application and then on the server side, you check the ClientCertificate property of the HttpRequest instance exposed by the Request property on the current context.
Note that what you are doing is really a very bad idea, in that applications should never be assigned identity, only users. To that end, you should be authenticating each and every user that is using your app, not considering the application to be the identity. It's commonly considered a bad practice to do such a thing.
You can share credentials between the applications using ASP.NET Client Application Services.
Here are some resources:
Client Application Services
Client Application Services with Visual Studio 2008
Is your desktop app running on machines that are in the same domain as your web server (i.e. all in the same company)? If so, Integrated Windows Authentication is your easiest solution.
I think its best idea to use a web browser control inside the desktop application .
Then use the WebBrowser1.Document most probably
WebBrowser1.Document.Cookie
get if the user is singed in.
I also need to make sure this URL that
is used cannot be simply copied and
used from another location, so I'll
need to include some sort of
information in the encrypted value to
know where it's coming from.
If you store the encrypted value in a cookie or as a field in a form (POST request), then the credential is no longer in the URL and so it can't be easily copied (note that I said "easily").