I am currently playing with DotNetOpenAuth to make an ASP.NET (C#) website use OpenID instead of the normal login-password routine for user and session handling.
Up till now, I have added the DotNetOpenAuth.dll into my project and tried a test login page with the following:
<rp:OpenIdLogin ID="OpenIdLogin1" runat="server" />
When I run the page, I enter a valid myopenid url and the website redirects to the myopenid page, where I enter my password, and upon success, it returns back to my default.aspx, due to the following in my web.config:
<authentication mode="Forms">
<forms defaultUrl="/Default.aspx" loginUrl="~/Login.aspx"/>
</authentication>
Now that the user is "logged in", how can handle my session? At the moment, I don't know how I can, for example, check if the session is still alive or how to terminate the session.
My basic question is, how can I manage the session once the user is authenticated with OpenID ?
[Update]
I am now using the following to check for authentication: HttpContext.Current.User, and with that I can now check if a user is authenticated with a session.
Now is there a possible way on how I can "link" user details that are stored in my database with an openid account?
OpenID logins with the OpenIdLogin control are (by default) no different than a username+password login from ASP.NET's point of view. As you've discovered HttpContext.Current.User is set on each incoming HTTP request based on an HTTP cookie that ASP.NET FormsAuthentication sends to the browser in order to keep the session consistent from request to request. While you're in a page or its code-behind, the Page.User property is an even more convenient means.
But if you're doing access control, rather than check whether there's a logged in user in every page, it's best to use the <authorization> tag in your web.config file to force the user to be logged in before accessing certain pages or directories of pages.
As far as linking user details, the key you want to associate with your users' details is the OpenID Claimed Identifier, which is what OpenIdLogin automatically assigns to the Username value for FormsAuthentication. So you can retrieve or store user details in your database based on the value of HttpContext.Current.User.Identity.Name, which will be the reliable and proven unique value for each user.
Related
I have Asp.NET MVC application which gets logged in after secure Id and password authentication.
After login, when I go to developer tools in Web Browser and Copy the ASP.NET_SessionId Cookie and paste it in another browser without login with Id and password, It gets logged in.
Where this cookie is created? And how I can handle this vulnerability?
You are describing "session hijacking"
You should ensure that ASP.net requires https, and that cookies are not accessible to client side script, by adding this to web.config
<httpCookies httpOnlyCookies="true" requireSSL="true" />
You might also implement something like the SecureSessionModule in this article which generates some additional measures
Note the caveats
https://learn.microsoft.com/en-us/archive/msdn-magazine/2004/august/wicked-code-foiling-session-hijacking-attempts
Consider the setup where a list of ids and passwords are stored in a database on a server and when a user enters his login credentials then the code-behind verifies it against the server and sets values like Session["id"] Session["login"] to determine whether user has access to certain page.
When a user attempts to browse to a page, the page looks at session variables and then relocates the user if need be and adjusts the buttons on its page accordingly.
How secure is this setup.
The built in login and role functionality of asp.net seems too rigid so I was trying to explore other options.
The major flaw in using Session is that it could open up your site to a Session Fixation vulnerability. As the session is established when the user arrives on your site, it may be possible for the session ID to be discovered (e.g. by a MITM).
Example steps are as follows for this exploit:
User arrives on HTTP site, ASP.NET gives them a session and sends the session cookie to user.
Attacker reads the session cookie value.
User goes to login form (HTTPS), logs in and your id and login values are stored in the session.
The attacker sets their session cookie to be the intercepted value from step 2.
The attacker now has a valid, logged in session, hijacking the now logged in user.
For this reason alone, I would recommend using the built in login and role functionality as the auth cookie is not set until the authenticated session is established. If you insist on the session method, I would recommend you call Session.Abandon() to grant the user a new session upon login, so that their session is not the same as their previous, unauthenticated session.
Please also see my answer to this question: https://stackoverflow.com/a/18077422/413180
The Session State is a safe way to keep track of user log-ins. Assuming the default set-up (in process, cookie-based session), it will be just as secure as Forms Authentication. The exact level of security you get with it will depend on how you configure your Session State.
Cookieless session state -- this opens up some potential security loopholes (e.g. user shares the url that contains the session ID, user takes a screenshot that contains the URL with the session id, etc.)
Out of process session state -- If you are using a remote session state service (or a database for storing the session), your Session's security will depend on you locking down access to the session state service or DB appropriately.
That said, the built-in login and role functionality that you get with Forms Auth is not too difficult to extend and build upon, rather than rolling something from scratch. If you need something custom, you can also write your own membership and role providers. This is helpful if you need to lock down routes based upon user name or role, as you can do it right in the web.config.
I have several applications and one of them is a central application that manages authentication, and where a LogOn page is imported from as an IFrame to the other applications.
When the userName and password are correct, I create a cookie named userInfo.
Now, in the current app, I want to check if the cookie of userInfo exists. I think I should check it exists in the browser (in client side).
It must be possible, so how can I do it ?
Thanks in advance.
Cookies cannot be shared cross domain. If your applications are not hosted on the same domain you have to forget about this. It won't work because browsers (for obvious security reasons) do not send cookies cross domain. There are other ways to implement cross domain single sign on (see the second part of my answer).
Now let's suppose that your applications are on the same domain and you have multiple applications spread over different sub-domains of the root domain:
login.foo.com
app.foo.com
xxx.foo.com
and you want to share authentication between those sub domains. All you have to do is specify set the domain property in your web.config to the root domain:
<authentication mode="Forms">
<forms
loginUrl="https://login.foo.com"
requireSSL="true"
protection="All"
timeout="120"
domain="foo.com"
slidingExpiration="false"
name="sso" />
</authentication>
The same configuration should be applied to the web.config of all applications. And that's pretty much all you need to do. Once the user is authenticated on one of the sub domains he will automatically be authenticated on the others thanks to the fact that cookies can be shared cross sub domains.
If you want to achieve cross domain single sign on then you will have to take a different approach. You could use the same machine keys between the different applications to encrypt the authentication token. Here are the steps:
User navigates to https://foo.com and is presented with a Logon screen because he is not authenticated on this domain yet.
The user authenticates and an authentication cookie is emitted and valid for the foo.com domain.
Now the user needs to go to https://bar.com and be automatically authenticated on this domain. On some page on https://foo.com you could create a form containing the value of the authentication cookie to be posted:
<form action="https://bar.com" method="post">
<input type="hidden" name="token" value="PUT THE VALUE OF THE AUTHENTICATION COOKIE HERE" />
<button type="submit">Go to bar.com</button>
</form>
The user submits the authentication cookie to the bar.com. The script that receives this form submission reads the authentication token value that was posted and uses the FormsAuthentication.Decrypt method to decrypt the authentication ticket and read the user name. Since both applications on foo.com and bar.com use the same machine keys, the ticket that was encrypted on foo.com will be successfully decrypted by bar.com
The script at bar.com having extracted the authenticated username from the token, it emits a forms authentication cookie valid on bar.com using the FormsAuthentication.SetAuthCookie method.
The user is now authenticated on bar.com
The whole security of this model relies on the fact that SSL is used when POSTing the forms authentication token from foo.com to bar.com so the token cannot be captured by a man-in-the-middle and that both applications share the same machine keys for encrypting and decrypting those tokens.
I've got an asp:LoginStatus control, which is supposed to change to 'Log out' when a user logs in.
However, I have not managed to create the login process. I've coded the login process myself using a Session (i.e. a database is checked to validate user-provided username and password, and if valid, my code sets a Session to true, and redirects to the page which he/she may now access).
There should be no problem with the above part, as it works well. The problem is with this LoginStatus control. I have read that the control checks for isAuthenticated, but I don't know how to set this property. Can the LoginStatus only be used with cookies, and is it not working due to my Session method of authentication?
I've set the login page and authentication type to "Forms" in the Web.config.
Any suggestions?
You have to mimic what the login control does; it uses FormsAuthentication.SetAuthCookie to establish the user security cookie, then redirects from the login page. That's what you have to use for testing. You have to do a redirect because during the lifecycle when you set the cookie, the framework doesn't think your logged in, until after the redirect.
I am developing a large asp.net based application. Certain pages & links require user authentication. At some page, I have links and form submission for which I first need to authenticate the user. Here is an example:
In PageX I have a link L1. When user click, i check if user is authenticated or not. If not I redirect to login page. Once, the user is authenticated, I redirect back him to the PageX. But the problem is, I don't want the user to click L1 again! Instead, I want the L1 action to be executed once user is authenticated and its results displayed etc.
I am trying to have a good solution to this problem. Any idea on how to accomplish this?
ASP.NET's Forms Authentication addresses this scenario. You can deny all unauthenticated users to all pages or (more commonly) deny unauthenticated users to a proper subset of pages.
there are several way of doing it:
1, The build-in way of Form Authentication, correct me if i remembered wrong, you should be able to add your own login logic and integrate your login control with Form Authentication provider
2, assign L1 url link to query string or a session if user is not login, and add logic to your login control, redirect user when login is successful.
Use Forms Authentication.
It's baked into ASP.NET and does exactly what you're talking about.
The User will click on a link. If they're not authenticated, they will be redirected to a login page (one of the parameters to the page will be the destination URL they were trying to reach). After a successful login, the User will be redirected to the page they requested instead of having to click the link again.
You also need to make sure you have your web.config set up to properly allow/deny unauthorized access to your application as described here:
Setting authorization rules for a particular page or folder in Web.config