{"id":2187,"date":"2013-05-08T23:30:51","date_gmt":"2013-05-09T06:30:51","guid":{"rendered":"http:\/\/www.cloudidentity.com\/blog\/?p=2187"},"modified":"2013-05-08T23:32:04","modified_gmt":"2013-05-09T06:32:04","slug":"sliding-sessions-for-wif-4-5","status":"publish","type":"post","link":"https:\/\/www.cloudidentity.com\/blog\/2013\/05\/08\/sliding-sessions-for-wif-4-5\/","title":{"rendered":"Sliding Sessions for WIF 4.5"},"content":{"rendered":"<p><img decoding=\"async\" alt=\"\" src=\"http:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/e\/e5\/%E5%85%AB%E4%BB%99%E6%B0%B4%E4%B8%8A%E6%A8%82%E5%9C%921.JPG\/640px-%E5%85%AB%E4%BB%99%E6%B0%B4%E4%B8%8A%E6%A8%82%E5%9C%921.JPG\" \/><\/p>\n<p>As it turns out, sliding sessions &#8211; sessions that are kept active by user\u2019s activity, as opposed to sessions with a static expiration time &#8211; are quite a popular topic as of late.<\/p>\n<p>I <a href=\"https:\/\/www.cloudidentity.com\/blog\/2010\/06\/16\/warning-sliding-sessions-are-closer-than-they-appear\/\">already covered the topic in details 3 years ago<\/a> (time flies!!!) but of course at the time I wrote all of the sample code with WIF 3.5. I am inclined to say that not much changed in this department, you can pretty much use the same technique as long as you fix namespaces and class names here and there, but from the number of people that asked about this I am clearly underestimating the difficulty of the task.<\/p>\n<p>So, how about the following: if you are interested in learning how to do this <a href=\"https:\/\/www.cloudidentity.com\/blog\/2010\/06\/16\/warning-sliding-sessions-are-closer-than-they-appear\/\">head to that old post and read through the theory<\/a>, so that I won\u2019t have to re-write it here; I\u2019ll be waiting here, and once you\u2019re back I\u2019ll show you the code that will work with .NET 4.5. Deal?<\/p>\n<p>[\u2026]<\/p>\n<p>Welcome back!<\/p>\n<p>Let\u2019s add sliding sessions to one typical WIF-based app, MVC or WebForm will both work. Here there are the steps:<\/p>\n<ul>\n<li>Add references to System.identityModel.dll and Sistem.identityModel.Services.dll<\/li>\n<li>Open global.asax.cs. Add the following usings:<\/li>\n<\/ul>\n<pre class=\"csharpcode\"><span class=\"kwrd\">using<\/span> System.IdentityModel.Services;\r\n<span class=\"kwrd\">using<\/span> System.IdentityModel.Tokens;<\/pre>\n<style type=\"text\/css\"><!--\n.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, \"Courier New\", courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt \n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }\n--><\/style>\n<ul>\n<li>next, add the method below. Note, I am assuming you kept the default names for the WIF Http modules in config<\/li>\n<\/ul>\n<pre class=\"csharpcode\"><span class=\"kwrd\">void<\/span> SessionAuthenticationModule_SessionSecurityTokenReceived(<span class=\"kwrd\">object<\/span> sender,<\/pre>\n<pre class=\"csharpcode\">                System.IdentityModel.Services.SessionSecurityTokenReceivedEventArgs e)\r\n{ \r\n    DateTime now = DateTime.UtcNow;\r\n    SessionSecurityToken sst = e.SessionToken;\r\n    DateTime validFrom = sst.ValidFrom;\r\n    DateTime validTo = sst.ValidTo; \r\n    <span class=\"kwrd\">if<\/span> ((now &lt; validTo) &amp;&amp; (now &gt; validFrom.AddMinutes( (validTo.Minute - validFrom.Minute) \/ 2)) ) \r\n    { \r\n        SessionAuthenticationModule sam = sender <span class=\"kwrd\">as<\/span> SessionAuthenticationModule;\r\n        e.SessionToken = sam.CreateSessionSecurityToken(sst.ClaimsPrincipal,<\/pre>\n<pre class=\"csharpcode\">                                                        sst.Context,<\/pre>\n<pre class=\"csharpcode\">                                                        now,<\/pre>\n<pre class=\"csharpcode\">                                                        now.AddMinutes(2),<\/pre>\n<pre class=\"csharpcode\">                                                        sst.IsPersistent); \r\n        e.ReissueCookie = <span class=\"kwrd\">true<\/span>; \r\n    }\r\n}<\/pre>\n<style type=\"text\/css\"><!--\n.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, \"Courier New\", courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt \n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }\n--><\/style>\n<p>I already explained the code in the old post, hence I won\u2019t go through that again here.<br \/>\nRather, I\u2019ll just add a couple of headsup that might save you some time when you\u2019ll test the feature:<\/p>\n<ul>\n<li>WIF has a default clockskew of 5 minutes: that\u2019s a tolerance which accounts for possible differences in the clock of the machine where your app runs and the machine that issued the authentication token. Given that the code sample above mints cookies that are valid for just two minutes, that\u2019s kind of hard to test if the code really works <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/05\/wlEmoticon-smile.png\" \/> one possible trick is to temporarily put the clockskew to zero. That\u2019s very straightforward, you just need to use the maximumclockskew attribute value to zero in the identityConfiguration element<\/li>\n<\/ul>\n<pre class=\"csharpcode\"> <span class=\"kwrd\">&lt;<\/span><span class=\"html\">identityConfiguration<\/span> <span class=\"attr\">maximumClockSkew<\/span><span class=\"kwrd\">=\"0\"<\/span><span class=\"kwrd\">&gt;<\/span><\/pre>\n<style type=\"text\/css\"><!--\n.csharpcode, .csharpcode pre\n{\n\tfont-size: small;\n\tcolor: black;\n\tfont-family: consolas, \"Courier New\", courier, monospace;\n\tbackground-color: #ffffff;\n\t\/*white-space: pre;*\/\n}\n.csharpcode pre { margin: 0em; }\n.csharpcode .rem { color: #008000; }\n.csharpcode .kwrd { color: #0000ff; }\n.csharpcode .str { color: #006080; }\n.csharpcode .op { color: #0000c0; }\n.csharpcode .preproc { color: #cc6633; }\n.csharpcode .asp { background-color: #ffff00; }\n.csharpcode .html { color: #800000; }\n.csharpcode .attr { color: #ff0000; }\n.csharpcode .alt \n{\n\tbackground-color: #f4f4f4;\n\twidth: 100%;\n\tmargin: 0em;\n}\n.csharpcode .lnum { color: #606060; }\n--><\/style>\n<ul>\n<li>If you are testing this against an STS that does save session cookies of their own, and the STS cookies outlive the ones in your RP, invalidating the RP\u2019s cookie would not make much difference: you\u2019d just be redirected to the STS, where you are already authenticated, and you\u2019d silently obtain a new token for the RP. If that\u2019s your setup, you might consider triggering a full fledged signout. Anyway, for testing purposes here there\u2019s what I did: once signed in the RP I opened another tab in the same browser instance, navigated to the IdP, opened the browser\u2019s developer tool and cleaned up the cookies for the IdP\u2019s domain. Then I waited 3 minutes, and sure enough when I tried to access a different route on the RP I got the familiar STS prompt instead <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2013\/05\/wlEmoticon-smile.png\" \/><\/li>\n<\/ul>\n<p>Well, that\u2019s it. I hope this will be useful; if this matter taught me something, it\u2019s that I have a blind spot for what things are difficult in the migration process between WIF versions. In fact, if there are areas where you find that the migration from WIF 3.5 to .NET 4.5 is less than straightforward, please let us know and we\u2019ll see what we can do to help!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As it turns out, sliding sessions &#8211; sessions that are kept active by user\u2019s activity, as opposed to sessions with a static expiration time &#8211; are quite a popular topic as of late. I already covered the topic in details 3 years ago (time flies!!!) but of course at the time I wrote&#8230;<\/p>\n","protected":false},"author":1,"featured_media":2188,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2187","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/2187","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/comments?post=2187"}],"version-history":[{"count":2,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/2187\/revisions"}],"predecessor-version":[{"id":2190,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/2187\/revisions\/2190"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media\/2188"}],"wp:attachment":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media?parent=2187"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/categories?post=2187"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/tags?post=2187"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}