For example: if I am retrieving User.Identity.Name, does it come from .ASPXAUTH cookie or is retrieved from the database using my membership provider?
Are any database requests made when I access User.Identity?
Thanks.
EDIT: Right now I am pretty sure it comes from an authentication ticket cookie, but can't find any official documentation to confirm this. Anyone?
This should answer your question...
"The forms authentication ticket not only includes the user's identity, but also contains information to help ensure the integrity and security of the token." Excerpted from the following Microsoft article:
http://www.asp.net/security/tutorials/forms-authentication-configuration-and-advanced-topics-vb
In addition to that explanation, observing ASP.NET behavior also supports the conclusion that the username is, in fact, stored in the ASPXAUTH cookie: ASP.NET does NOT hit the database on subsequent page requests after the user has been authenticated. You can prove this yourself, just as I did, by running SQL Profiler to monitor the database as it is used by an ASP.NET application.
Also know that username and authentication ticket data are NOT stored in session state. Aside from raising security concerns, that kind of implementation would cause ASP.NET Membership to break when session state is disabled. Here is another Stack Overflow answer indicating that Forms Authentication (Membership) data and Session State have nothing to do with one another:
Does FormsAuthentication.SetAuthCookie() make a session based cookie?
That answer also links to an MSDN article, here, that explains the ASPXAUTH cookie in detail, though the article I referenced above seems to be more current.
I believe the authentication information are specific to a session and maintained within the ASP.net process or outside or even SQL server. Once a user is authenticated a session token is generated, the token is used to track information of the authenticated user in the state service. On subsequent requests, the session token is used to retrieve user identity and thats where we get pre-populated objects like User.Identity.Name. this must be implmented either in Forms Authentication module or windows authentication module depending on the type of authentication one is using. If you set to cookieless authentication mode, the session token is displayed within the URL. Once the session expires, all the information pertaining to the session is removed from the state service.
Hope this makes it clear!
It depends on the type of Session you are using. Sessions can be varied by using two parameters
1. Use of Cookies-Cookieless, Or use cookie
2. Process to store the session state information -Inproc (in process), outproc (ASP.net state service), or Sql Server.
If you use Sql Server to store the state information, a data base query will certainly be made to fetch the session data.
More details here-
http://www.codeproject.com/KB/aspnet/ExploringSession.aspx
.ASPXAUTH cookie / User.Identity comes from authentication (Windows, Forms).
If you are trying to get the user for Membership you need to use
Membership.GetUser()
or
Membership.GetUser(User.Identity.Name )
documentation here which would result in a DB call.
Related
I've successfully used cookies before and I'd like to begin using JWT. My biggest question is how to pass your token to a website during the initial GET operation, for example when a user types your domain into their address bar or clicks on a link from some other website like google.
When using cookies for example, if you type stackoverflow.com into your web browser, the persistent cookie is sent to the website which seamlessly allows your own stackoverflow session to be automatically authorized.
I am aware that I can programatically pass my JWT token via a javascript GET through the HTTP headers but how do you pass the token when a visitor types in your URL into their web browser?
Possible solution #1
My thoughts have been to have javascript code check if 'authorized'. If not, check for a JWT token in local storage. If found, redirect to the same address. The problem of course would be that there is no way to pass the token during a redirect.
Possible solution #2
Similar to above but not issuing a redirect, I would update the current page to reflect the 'authorized' state.
Possible solution #3
Use a permanent cookie containing the JWT token. I am thinking that this 3rd option would be the best. If I did this, there would be no need to pass the JWT via an HTTP header.
I've thought about this for a few days, read up on JWT and here are my conclusions for avoiding JWT in my particular case:
No easy way to authorize a user who opens their browser and types in your website. With cookies, your server immediately knows how to respond to this headerless GET request.
No way to easily change the JWT token signature. All users are immediately affected by such a change, essentially forcing everyone to authenticate again.
No way to easily invalidate a specific JWT token. The best you can do is to maintain and check a banned signature list on the server. This of course would require a centralized or distributed server method almost identical to a cookie session management system. This would force a coupling between the token and the server, no longer stateless as intended by JWT.
SUMMARY
Cookie management requires more server infrastructure but you have much greater session control. State is seamless (in the case of #1 above). You can instantly invalidate state. For example, the user can log out (deleting the session at the server level) or the session can be instantly banned by an administrator by simply deleting the session.
I also see the benefits to JWS:
no need to hit the db or cache system when authorizing.
simple authorization between multiple servers having the secret key.
simple authorization, no session management programming and no db session state storage required.
...but the drawbacks stated previously are too great for my particular needs.
Scenario:
1) you are implementing a website/webserver that supports SSO (SPNEGO).
2) A client connects to you and provides you a ticket which is valid, so access is granted to the client
Question - At this point, should I implement some mechanism such as a cookie that allows for the client to no longer generate tickets (Storing some value that can be cached client side and used for subsequent calls) ? How long/how many requests can I honor the same spnego token? I tried finding the answer for the second question and could not find an answer.... What is the "MAXLIFE" of a token that you can generate for a SPNEGO token?
The first question/answer clearly depends on your usecase. If you have a website with a browser, a session cookie, e.g. JSESSIONID, is the way to go. If this is some library, it has to support cookies. Thoughly, ticket generation is extremely fast.
Second question: Do not fiddle with the tickets. They cannot be reused and will throw an exception: this is a replay. Pass those tokens to SSPI/GSS-API and throw the context away when the auth is completed. As soon as the server nags you again, create a new context and send a new token.
By default, a ticket is valid for 10 hours in Active Directory but this can be changed by the admin. Use kerbtray.exe on Windows or klist on Unix to see the lifetime of your tickets.
A comment below an answer about state and REST recently piqued my interest. For clarity I'll quote the comment in full:
Nothing in my answer implies a solution based on database access on every request, if you think it does, it is a failing on your part to understand authentication and authorization at that scale. The authentication can be implicit in the state, do you think that facebook does a "database access" on every request of its REST API? Or Google for that matter? hint: no
I tried to think how one might authenticate without checking a user-provided value against a centrally-held one, even if one to know what data to display to the user, and came up blank. i freely admit this is a failing on my part to understand authentication and authorization at that scale. My question is therefore: how do sites like Facebook and Google accomplish this?
One way is claims based authentication. Simplified and somewhat loosely interpreted, it boils down to this;
Instead of the server application authenticating the user itself, an un-authenticated user is redirected to a separate authentication server.
The authentication server validates the user in any way it wants to (login+password, certificate, domain membership etc) and creates a signed "document" with the relevant user info (user id, name, roles, ...) It then redirects the user back to the server application with the document enclosed.
The server application validates the signature of the document, and if it trusts the signature, it can use the document contents to assume who the user is instead of accessing the database.
Normally, the server application caches the document in a cookie/session or similar so that the next access to the application does not have to bounce through the authentication server.
In this way, the server application does not need to concern itself with how the user is authenticated, just whether it trusts the judgement of the authentication server. If the authentication server (and possibly the client unless it's a browser) adds Facebook login support, the server application will automatically "just work" with the new login type.
I am building a messaging application using BackboneJS which naturally persists using a REST interface.
The issue I'm having is that I don't know how to restrict what data a user can pull back from the API. For instance a call to /messages would, at the moment, return messages for ALL users. I would like that resource to only return messages belonging to the current user.
Searching online seems to indicate that oAuth2 is the best way to solve this issue but all the tutorials talk about been redirected to another place to confirm access and retrieve an access token.
Given that my users will have already logged into the message application and that the REST API is actually part of the same application I don't like the idea of asking the users to confirm that my own app can access my own API.
Is there a better way?
oAuth2 is probably your best bet -- you definitely don't want to roll your own security. However, the flavor of oAuth2 you are thinking of is probably not what you want.
oAuth2 has four different flavors, known as authorization grant types:
Authorization code: This is the type you are thinking about. It is often called three-legged oAuth, because there are three actors in the token granting process (app, resource owner, and user). The app asks the user whether it is ok for the resource owner to give specific type(s) of access to the resource. It is a rather complex process that allows the validation of user credentials without allowing the app access to them. This is not necessary in your case, since you are both the app and resource owner.
Client credentials: This is a method for authorizing a client application with the server. It does not use user credentials at all. If you completely trust your client application (all client applications) to correctly protect user data and not expose other user's data to the user using the app, or you are providing only non-user data via the API (for example, map data or catalog data), you might be able to use this fairly simple type of oAuth2. However, if you want to be vigilant in protecting user data (and not allow apps to get to the data without the user providing credentials), you might not use this one.
Resource owner password credentials: The username and password of the user is passed via https to your backend server, which authenticates and authorizes access by providing an access token. The access token can then be passed with each call, and it remains valid for accessing the backend until a configurable time period has elapsed. This means that someone intercepting the token could only use it successfully for a limited amount of time (some number of minutes, generally). The interceptor would not know the username and password of the user. In addition, you can supply the app with a refresh token, which can be used to get a new access token once it has expired (until the refresh token expires -- usually with a significantly longer expiration date). Since the credentials are not passed across the wire often (and must only be passed encrypted), this is often the best solution for protecting user credentials and not requiring the user to pass them in often (good user experience). Implementation is much simpler than for the authorization code grant type.
Implicit: This is the least secure method -- no credentials are validated server side at all. This is usually used for client side scripting languages where credentials cannot be stored safely. If you are worried about security at all, avoid this type if possible.
So, check out OAuth 2.0, and look for the resource owner password credentials grant type.
I'm going to develop site accessible to anonymous and registered users. Planed security schema is similar to let's say YouTube and most of others "web 2.0" sites. Logged user will get access to more functions, more data etc. What is best approach to implement that?
I'm thinking about create simple service returning random session code to client, and adding session object to singleton application object. When user provide credential, I'll change parameter "logged" in his session object. Session token will be passed as one of parameters in every single request, and services will change their behavior if user is registered or not (i.e. there will be returned only "public" data, or restricted content only)
Is it good approach, or should I use something different?
There is nothing inherently different about GWT security, it is the same with JSP,PHP, ASP, ROR, etc..., that is web application security.
There is already a session mechanism on the server side, that generates secure random session cookies, use it. As a bonus, it handles session expiration and other things you would have to handle if you rolled your own.
You cannot trust ANYTHING the client sends you, so if you send the username or some kind of token from the client to the server (other than the user logging in), you are doing it wrong.
If your information has any value, force SSL on all connections.
Your implementation of the server calls should check the server session for the current user info, and determine if the user is authorized to perform the action. Again, your RPC information should not include any information about the user making the call, other than the session cookie that is sent automatically with the request headers. Anything you store, such as whether the user is logged in, should be in the server side session.
Of course, you need to do something on the client to present logged in and anonymous users with the proper user interface. But that is not security, only work to present a consistent interface. All the security is on the server side.