Session Token JavaScript Sample for Thinktecture.IdentityModel and Web API

Christian has added a new JavaScript sample that shows how to use the session token mechanism. It includes persisting the session token in local storage. Nice!

github

This entry was posted in IdentityModel, WebAPI. Bookmark the permalink.

17 Responses to Session Token JavaScript Sample for Thinktecture.IdentityModel and Web API

  1. Eric B says:

    This isn’t really JWT specfic, but this example highlighted a question that’s been nagging me for a while. Once a web client has an authorization token, say JWT, why go through all the hurdles in this example (Lawnchair, retrieving the value from storage & attaching the header to every AJAX request, etc…) ?

    Why not just use IdentityModel’s HeaderMapping capability and store the token in a cookie? This way it will be automatically transported with requests. I also won’t need to reinvent a persistent cross-session storage mechanism, like above.

  2. Hi,

    good question.

    I wanted an explicit model – that very much mimics the way you would deal with a “real” token service.
    In particular I wanted to avoid coupling the session with a transport mechanism, since for non JS clients, that might mean that the session is coupled with the client HTTP connection (like a .NET cookie container).

    But you are right – for a JS client the cookie solution would be much easier. But,

    – Can you query the expiration of a cookie from JS? Maybe I want to pro-actively get a new session token before the old one expires.
    – Cookies have a size limit, and I don’t really want to get into the business of chunking the token. Also allowd cookie size varies between browsers.

    Maybe I’ll add this feature….but need to think more about it.

  3. doogie04 says:

    Thanks for the reply. Also, welcome to StackOverflow. I noticed you recently popped up so I upvoted some of your answers and added a Thinktecture-Ident-Model tag :-D.

    FEATURE?
    I wasn’t really asking for a feature…although I do think it would help ease adoption of ‘outsourced authentication’ in web scenarios. I like the decoupling. I like that the solution is applicable to more than just HTTP scenarios; although IdentityModel already wades deep into the HTTP river (e.g., attributes & message handlers, HeaderMapping tokens from cookies, etc..).

    PRAGMATISM
    I’m really just trying to piece together a coherent/holistic picture of how to integrate token based authentication into a *web app*. I’ve yet to find a major site that actually relies on a token for in-site authorization (as opposed to initial-auth/logon). Major sites that use a token service (like hotmail, gmail, stack overflow, etc…) all seem to take the token and convert the necessary parts into a cookie. Using a cookie seems to be the pragmatic decision. First, the cookie just flows with transport. Second, if you have restricted assets, like say images that are somehow restricted, it would be quite difficult to inject the www-authenticate header for requests that naturally flow from the browser loading the HTML.

    SIZE CONSTRAINTS
    As for size constraints, as a practical matter they exist & vary whether using HTTP Headers (8k – http://stackoverflow.com/questions/686217) or cookies (4k – http://stackoverflow.com/questions/3107140). The pragmatist in me also thinks that if I need to transport over 4k of claims for every request — you’re going to have issues in the web world, particularly with mobile scenarios. I understand the need to exceed 4/8k, but I see those as more of an initial logon, data-import or establish-an-account process, rather than “here is my token, can i view this web page?”.

    TOKEN EXPIRATION
    Using JavaScript, the cookie expiration is opaque and cannot be read (http://stackoverflow.com/questions/1532193). The cookie exists, until it doesn’t.

    I do not, however, see this as a significant limitation. If the cookie is not encrypted, the client can just read the ValidTo/expiration claim value inside the cookie. If the token is encrypted the client cannot read the upcoming expiration regardless of the transport methodology (wwwauth or cookie).

    I see a few ways to address the shortcoming. One, if the coder is so inclined, he could add a buddy-cookie that sets the expiration time as a value. Ugly, but easy. Alternately, the client and web server need to have a process for re-authentication in place, irrespective of using a token, an old school session cookie, or whatever. Why not just have the web server return a HTTP 401 with an appropriate www-authenticate header, and additional information if so desired. The client then asks the token service for a refreshed token. The token server can respond with either a refreshed token (if appropriate), or a 401 indicating client needs to provide credentials anew.

    Anyway, I’m new to the claims based authentication, but that’s my 2-cents.

    • wrt Feature:
      Oh yeah this is used outside of HTTP (e.g. in SOAP) – WIF supports that pretty well out of the box. My library is just adding the missing pieces for HTTP.

      wrt Token Expiration
      I need to look up the OAuth2 spec – I think they have a special status code/reason for expired tokens.

      I guess you can summarize like this:
      For “native” clients, the token response approach is better (because there is no coupling with the http client)
      For JS clients, the cookie approach is better (because it just works).

      I guess I will add a switch to my config, so you can decide which style you want. On my todo list now ;)

      • Josh says:

        I would like to use the cookie approach for my js client. Was this “switch” you mentioned ever added to the config? If not, is there an example of how to use the HeaderMapping functionality that Eric B mentioned above?

  4. ivarkatmo says:

    Hi…

    Maybe off-topic but when I in the example type wrong password I get the browsers integrated logon dialog. How do I prevent it from poping up?

    Ivar

    • Hmm – try setting the default authentication scheme to empty in the authentication config. I guess the “Basic” triggers the login dialog in the browser…

      • OK – i verified this.

        The dialog box will popup when an www-authenticate header is present in the response. When you remove the header, no dialog will appear.

        In the 4.5 version, you can set a property on AuthenticationConfig called SendWwwAuthenticateResponse to suppress the header. This will be backported to 4.0 as well.

  5. schoepfiThomas says:

    Hi there…
    Is there a Issue or a (strange miss-) behavior known according to a cross-domain ajax calls (to the tokenservice whos adressed on an differed domain obviously) on Christians’ JavaScriptClients Example. e.g. file brokeredAuthentication.js.

    • Well – it works on my machine – also cross domain.

      The target service needs to implement CORS (like my sample does).

      • Hans says:

        Hi Dominick,

        Is it correct to say that the correct behavior of a CORS implementation depends on the browser that the client uses? Calling a web.api using a MVC 4 project with js and Ajax from an IE9 browser for example, is still not working if i implement CORS (access denied).

        After the user is autheticated using a username/password (Membership) via basic authentication he recieves a token. This token is stored in a cookie and the tokenvalue is send in the following calls to the web.api. On my dev machine thinks worked ok, however when I uploaded this solution to Azure the access denied messages came up.

        Just when I thought JSONP could be the solution, I found out that setting a custom header is not possible. So that’s is also no solution. Using a httpclient serverside connecting to the web.api has no issue, but using Ajax to fill a page with a lot of tiles is the prefered solution.

        The web.api should also be available for mobile device using a native app or the browser.

        What should be the correct solution?

  6. brockallen says:

    @Hans — CORS has to be implemented by the browser:

    http://caniuse.com/#search=cors

    IE8 and IE9 sort of support it, as long as you use the XDomainRequest (instead of the XmlHttpRequest) for your Ajax calls. This has been fixed in IE10.

  7. @Josh – Cookies are not supported. I decided against it. A number of problems come with cookies – CSRF – sliding expiration etc. Go with the “token request” approach, which makes it much more painless to switch to a real token service at some point.

  8. Brett says:

    Dominick,

    The link is broken to this project. I downloaded the latest 4.5 project and this web client is not included. Where can I find the code to include the JWT in each response to the client. In my scenario the token will be used in subsequent AJAX calls to other Web APIs.

    Thanks,

    Brett

  9. Brett says:

    The JavaScript client mentioned in this post is not included in the Identity Model 4.5 sample solution. I would greatly appreciate it if you included it.

Leave a Reply to brockallen Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s