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!
-
Recent Posts
Categories
- .NET Security (95)
- ASP.NET (163)
- ASP.NET Core (27)
- AuthorizationServer (33)
- Azure (29)
- Conferences & Training (40)
- IdentityModel (347)
- IdentityServer (205)
- Katana (46)
- OAuth (163)
- OpenID Connect (94)
- OWIN (45)
- Photography (14)
- PolicyServer (3)
- Resources (1)
- Uncategorized (625)
- WCF (109)
- WebAPI (223)
Tweets
Tweets by leastprivilegeFeed
Archives
- May 2021
- October 2020
- July 2020
- June 2020
- May 2020
- April 2020
- March 2020
- February 2020
- January 2020
- September 2019
- August 2019
- July 2019
- June 2019
- April 2019
- February 2019
- January 2019
- December 2018
- July 2018
- June 2018
- May 2018
- February 2018
- January 2018
- December 2017
- November 2017
- October 2017
- August 2017
- July 2017
- May 2017
- April 2017
- March 2017
- February 2017
- January 2017
- December 2016
- October 2016
- September 2016
- August 2016
- July 2016
- June 2016
- May 2016
- February 2016
- January 2016
- December 2015
- November 2015
- October 2015
- September 2015
- July 2015
- June 2015
- May 2015
- April 2015
- March 2015
- February 2015
- January 2015
- December 2014
- November 2014
- October 2014
- September 2014
- August 2014
- July 2014
- June 2014
- May 2014
- April 2014
- March 2014
- February 2014
- January 2014
- December 2013
- November 2013
- October 2013
- September 2013
- August 2013
- July 2013
- June 2013
- May 2013
- April 2013
- March 2013
- February 2013
- January 2013
- December 2012
- November 2012
- October 2012
- September 2012
- August 2012
- July 2012
- June 2012
- May 2012
- April 2012
- March 2012
- February 2012
- January 2012
- December 2011
- November 2011
- October 2011
- September 2011
- July 2011
- June 2011
- May 2011
- April 2011
- March 2011
- February 2011
- January 2011
- December 2010
- November 2010
- October 2010
- September 2010
- August 2010
- July 2010
- June 2010
- May 2010
- April 2010
- March 2010
- February 2010
- December 2009
- November 2009
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006
- August 2006
- July 2006
- June 2006
- May 2006
- April 2006
- March 2006
- February 2006
- January 2006
- December 2005
- November 2005
- October 2005
- September 2005
- August 2005
- July 2005
- June 2005
- May 2005
- April 2005
- March 2005
- February 2005
- January 2005
- December 2004
- November 2004
- October 2004
- September 2004
- August 2004
- July 2004
- June 2004
- May 2004
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.
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.
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 ;)
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?
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.
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).
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?
@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.
@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.
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
It is probably here:
https://github.com/thinktecture/Thinktecture.IdentityModel.45/tree/master/Samples/Web%20API%20Security/Clients
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.
https://github.com/thinktecture/Thinktecture.IdentityModel.45/blob/master/Samples/Web%20API%20Security/Clients/JsBasicAuth/default.cshtml