{"id":275,"date":"2012-07-17T01:02:00","date_gmt":"2012-07-17T10:02:00","guid":{"rendered":"http:\/\/www.cloudidentity.com\/blog\/2012\/07\/17\/inside-the-windows-azure-active-directory-web-sso-sample-for-java-2\/"},"modified":"2012-07-17T01:02:00","modified_gmt":"2012-07-17T10:02:00","slug":"inside-the-windows-azure-active-directory-web-sso-sample-for-java-2","status":"publish","type":"post","link":"https:\/\/www.cloudidentity.com\/blog\/2012\/07\/17\/inside-the-windows-azure-active-directory-web-sso-sample-for-java-2\/","title":{"rendered":"Inside the Windows Azure Active Directory Web SSO Sample for Java"},"content":{"rendered":"<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2012\/07\/7853.image_5F00_71D61F9E.png\"><img loading=\"lazy\" decoding=\"async\" style=\"margin: 0px;border: 0px currentcolor\" title=\"image\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2012\/07\/7853.image_5F00_71D61F9E.png\" width=\"305\" height=\"283\" \/><\/a><\/p>\n<p>By now I am sure you heard that <a href=\"http:\/\/blogs.msdn.com\/b\/windowsazure\/archive\/2012\/07\/12\/announcing-the-developer-preview-of-windows-azure-active-directory.aspx\">the Windows Azure Active Directory Developer Preview is out<\/a>.     <br \/>We announced so many interesting news that you might just have missed an interesting fact: as part of this release we made available a couple of samples developed on\u2026 something other than Visual Studio <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2012\/07\/7450.wlEmoticon_2D00_smile_5F00_487ED7A0.png\" \/> Namely, I am referring to <a href=\"https:\/\/github.com\/WindowsAzure\/azure-sdk-for-java-samples\">the Windows Azure AD SSO sample for Java<\/a> and the <a href=\"https:\/\/github.com\/WindowsAzure\/azure-sdk-for-php-samples\">Windows Azure AD SSO sample for PHP<\/a>. <\/p>\n<p>We provided detailed instructions on how to operate the Java sample, and I am told that the PHP one won\u2019t take long to bring out; however I think it would be interesting to provide you with some insights on how the project are structured and how they make the magic of claims-based identity happen. Add to it that my wife is out, and that if I\u2019d watch without the series finale of Eureka I\u2019d be in deep trouble\u2026 and you\u2019ve got yourself a blog post.<\/p>\n<p>Let\u2019s start with the <a href=\"https:\/\/github.com\/WindowsAzure\/azure-sdk-for-java-samples\">Java sample<\/a>. One word of warning: I already wrote a <a href=\"http:\/\/www.urbandictionary.com\/define.php?term=tl%3Bdr\">tl; dr<\/a> (thanks Ryan for labeling it that way <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2012\/07\/7450.wlEmoticon_2D00_smile_5F00_487ED7A0.png\" \/>) <a href=\"http:\/\/bit.ly\/OdBmCi\">post on how web SSO works in the developer preview<\/a>, and I am not going to repeat any of it here as most of it (modulo syntactic sugar) holds regardless of the language you use.<\/p>\n<h1>The Project<\/h1>\n<p>We wrote the Java sample as a <strong><a href=\"http:\/\/www.jboss.org\/\">JBoss<\/a><\/strong> project. Before you come down with a case of <a href=\"http:\/\/en.wikipedia.org\/wiki\/Apophenia\">apophenia<\/a> and read who-knows-what in it: when we first started to work on the code we were in contact with one partner who wanted to connect with Windows Azure Active Directory from a JBoss application (on Solaris!), hence it was natural for us to go that way.&#160; However it should be pretty easy for you (assuming that you know Java better than I do) to port the code to any other application server. Also, this would be a great time for me to thank the usual Southworks for their help on this project. Thanks guys!<\/p>\n<p>We worked with <a href=\"https:\/\/devstudio.jboss.com\/earlyaccess\/\">JBoss Studio<\/a>, from where I\u2019ll take most of the following screenshots. Also, we leveraged <a href=\"http:\/\/maven.apache.org\/\">Maven<\/a> for handling the many dependencies on the project.<\/p>\n<p>The project have two main components: a library you can reuse across different projects, and a sample JSP web application that shows those in action.<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2012\/07\/3240.image_5F00_55E4EAA6.png\"><img loading=\"lazy\" decoding=\"async\" style=\"margin: 0px;border: 0px currentcolor\" title=\"image\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2012\/07\/3240.image_5F00_55E4EAA6.png\" width=\"351\" height=\"505\" \/><\/a><\/p>\n<p>The package <strong>com.microsoft.samples.federation<\/strong> provides you with the basic building blocks for handling claims-based identity via WS-Federation in your Java applications. Here, I\u2019ll tell you a secret: the main hard rock when dealing with those scenarios is the SAML token handling itself, crypto verification, canonicalization, the whole brouhaha. Everything else is just a matter of triggering validation at the right times and in the right places; even ws-federation itself is really not that hard. In that optic, <strong>com.microsoft.samples.federation<\/strong> does the easy part of the job: we\u2019ll see i9t in details later. For the heavy lifting \u2013 the SAML token processing \u2013 why reinventing the wheel? We use <a href=\"https:\/\/wiki.shibboleth.net\/confluence\/display\/OpenSAML\/Home\/\">OpenSAML<\/a>, a well-known Java and C++ library for handling (I *absolutely* loathe the expression \u201ccracking a token\u201d) SAML tokens.<\/p>\n<p>The package <strong>com.microsoft.samples.waad.federation<\/strong> augments the basic federation capabilities in the former package with elements that are specific to Windows Azure Active Directory, such as the SPN-based realm validation described in the <a href=\"http:\/\/bit.ly\/OdBmCi\">SSO deep dive<\/a>.<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2012\/07\/0513.image_5F00_062BBF5D.png\"><img loading=\"lazy\" decoding=\"async\" style=\"margin: 0px;border: 0px currentcolor\" title=\"image\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2012\/07\/0513.image_5F00_062BBF5D.png\" width=\"317\" height=\"364\" \/><\/a><\/p>\n<h1>Handling Web SSO<\/h1>\n<p>How does the sample really work? In a nutshell: we put a blanket filter in front of all pages; that filter intercepts requests, redirects the unauthenticated ones to a login page and restores the claims from the session for the authenticated ones. The login page performs HRD and generates the proper signin message, taking care of indicating as ultimate return URL the address of a servlet which is equipped to extract tokens from wresult and process them as appropriate. Most of the token &amp; session processing logic is provided by the class ConfigurableFederatedLoginManager and its ancestor FederatedLoginManager.<\/p>\n<p>Too fast? OK, let\u2019s go through the same flow more in details. Here there\u2019s the structure of the web application:<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2012\/07\/1106.image_5F00_7951693E.png\"><img loading=\"lazy\" decoding=\"async\" style=\"margin: 0px;border: 0px currentcolor\" title=\"image\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2012\/07\/1106.image_5F00_7951693E.png\" width=\"700\" height=\"340\" \/><\/a><\/p>\n<p>The web site is really minimal, there\u2019s one resource (index.jsp) and one page to host the HRD experience (login.jsp).<\/p>\n<p>The WEB-INF\/web.xml carries the config: you can see part of it on the right side of the screenshot. From the top:<\/p>\n<ul>\n<li>We define the FederationServlet, associated with the homonym class, that will take care of handling incoming tokens.<\/li>\n<li>We define a filter, FederationFilter, which has direct knowledge of the URL of the HRD page. The filter also defines a series of exceptions, most notably login.jsp and the servlet endpoint<\/li>\n<\/ul>\n<p>\u2026and now comes the fun part. Aided by a good glass of Duvell, I debated a bit with myself about what would be the best way of walking you though the various classes and explaining what they contribute to the authentication flow. I concluded that walking through the files would end up forcing me to create a full reference documentation suite, which I don\u2019t have time to write (after all, an Eureka episode lasts barely one hour <img decoding=\"async\" style=\"style\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2012\/07\/7450.wlEmoticon_2D00_smile_5F00_487ED7A0.png\" \/>). Hence, the most concise way appeared to be creating a diagram of what happens from the first unauthenticated resource to the moment in which the caller finally gains access, and explains what happens at every stage. So, here you go:<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2012\/07\/3252.image_5F00_77A09D6A.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border: 0px currentcolor\" title=\"image\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2012\/07\/3252.image_5F00_77A09D6A.png\" width=\"512\" height=\"289\" \/><\/a><\/p>\n<p>Don\u2019t be scared, you\u2019ll see that it is fact pretty straightforward <img decoding=\"async\" style=\"style\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2012\/07\/7450.wlEmoticon_2D00_smile_5F00_487ED7A0.png\" \/> let\u2019s dive in!<\/p>\n<ol>\n<li>A client browser requests index.jsp. The request gets intercepted by the <strong>FederationFilter<\/strong>.<\/li>\n<li>The filter passes the request to the <strong>ConfigurableFederatedLoginManager<\/strong>, the handyman of this sample. <strong>ConfigurableFederatedLoginManager<\/strong> indicates that the request is not authenticated (as in, there is no session with claims in it), hence the filter redirects to <strong>login<\/strong>.<strong>jsp<\/strong> (but not before augmenting the request with a return url pointing to <strong>index<\/strong>.<strong>jsp<\/strong>, so that we can get back to it upon successful authentication)<\/li>\n<li><strong>login<\/strong>.<strong>jsp<\/strong> queries a repository of trusted issuers, which play the same role as <strong>TrustedIssuers<\/strong>.<strong>xml<\/strong> in the .NET sample, and uses the list of trusted IdPs to create a series of link which contain the correct WS-Federation signin requests for each of the Idps. NOTE: the requests are all designed to redirect authentication tokens back to the <strong>FederationServlet<\/strong> endpoint (https:\/\/localhost:8443\/sample\/wsfed-saml in this sample)<\/li>\n<li>The user clicks on a link, and the Windows Azure Active Directory user authentication dance begins<\/li>\n<li>Assuming that the user authentication took place successfully, the browser POSTs the resulting token to the servlet endpoint as instructed by step #3. The servlet also instantiates <strong>ConfigurableFederatedLoginManager<\/strong> and feed the incoming request to its <em><strong>authenticate<\/strong> <\/em>method. The method uses the trusted issuers repository for retrieving the necessary validation coordinates, then proceeds to validate the incoming token (using various other classes in the process)<\/li>\n<li>Upon successful authentication, the <strong>ConfigurableFederatedLoginManager<\/strong> saves the resulting principal (i.e. the claims) in the session<\/li>\n<li><strong>ConfigurableFederatedLoginManager<\/strong> raises the event <strong>OnAuthenticationSucceed<\/strong> for a <strong>FederatedAuthenticationListener<\/strong>. This is a bit like implementing the <strong>SignedIn<\/strong>() event in WIF: in this sample we really don\u2019t do anything with this, but that\u2019s substantially a way of offering a place in the pipeline where you can add custom processing logic outside of the application proper.<\/li>\n<li>Once all the validations are done, <strong>ConfigurableFederatedLoginManager<\/strong> retrieves from the request context (wctx) the URL of the resource originally requested (<strong>index<\/strong>.<strong>jsp<\/strong>, in our case) and redirects to it<\/li>\n<li>Here we get through the same flow as #2; however this time <strong>ConfigurableFederatedLoginManager<\/strong> finds a session and successfully retrieves the associated claims, hence\u2026<\/li>\n<li>\u2026the request finally reaches <strong>index<\/strong>.<strong>jsp<\/strong><\/li>\n<\/ol>\n<p>\u2026and that\u2019s the core of it! The rest is largely filling in the blanks with proper WS-Federation syntax, handling all the windows azure active directory-specific things I described in the deep dive, and so on. <\/p>\n<h1>Summary<\/h1>\n<p>This is not a complete reference, but hopefully it explains enough of the flow that it will help you to find your way as you explore the sample source. Also note: if you observe the flow and the various artifacts, you\u2019ll see how it hints to some interesting potential extensions. Say that in the future there will be another redirect-based protocol you want to support, like SAML-P or OpenID Connect: all you\u2019d need to do would be to add a servlet for the new protocol, enhance the FederatedLoginManager to recognize and enforce the protocol-specific flows, and orchestrate calls to whatever other support classes (such as for different token formats) you\u2019d want to onboard. Pretty neat <img decoding=\"async\" style=\"style\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2012\/07\/7450.wlEmoticon_2D00_smile_5F00_487ED7A0.png\" \/><\/p>\n<p>Of course I fully expect that the Java experts among you will have a ton of feedback about how we could have done this more efficiently, and we look forward to hear from you: but the hope is that this will help you to connect to Windows Azure Active Directory in a way that is closer to the practices and tools you are used to work with.<\/p>\n<p>Well, the Eureka series finale still awaits in the DVR downstairs: however it is now awfully late, hence I successfully avoided to watch it\u2026 for tonight. I guess that for tomorrow I\u2019ll have to find something else to write about <img decoding=\"async\" style=\"style\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2012\/07\/7450.wlEmoticon_2D00_smile_5F00_487ED7A0.png\" \/><\/p>\n<p> in the meanwhile, please send us your feedback on the dev preview of Windows Azure Active Directory! We already got very interesting observations from many of you guys (thank you!) but the game has just begun!<\/p>\n<div style=\"clear:both\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>By now I am sure you heard that the Windows Azure Active Directory Developer Preview is out. We announced so many interesting news that you might just have missed an interesting fact: as part of this release we made available a couple of samples developed on\u2026 something other than Visual Studio Namely, I&#8230;<\/p>\n","protected":false},"author":1,"featured_media":1319,"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":[23,9,12],"tags":[],"class_list":["post-275","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-federation","category-identity","category-windows-azure-active-directory"],"_links":{"self":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/275","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=275"}],"version-history":[{"count":0,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/275\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media\/1319"}],"wp:attachment":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media?parent=275"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/categories?post=275"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/tags?post=275"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}