{"id":318,"date":"2011-05-19T22:49:00","date_gmt":"2011-05-20T07:49:00","guid":{"rendered":"http:\/\/www.cloudidentity.com\/blog\/2011\/05\/19\/adding-a-custom-openid-provider-to-acs-with-just-one-line-of-powershell-code\/"},"modified":"2011-05-19T22:49:00","modified_gmt":"2011-05-20T07:49:00","slug":"adding-a-custom-openid-provider-to-acs-with-just-one-line-of-powershell-code","status":"publish","type":"post","link":"https:\/\/www.cloudidentity.com\/blog\/2011\/05\/19\/adding-a-custom-openid-provider-to-acs-with-just-one-line-of-powershell-code\/","title":{"rendered":"Adding a Custom OpenID Provider to ACS\u2026 with JUST ONE LINE of PowerShell Code"},"content":{"rendered":"<p>ACS offers you a variety of identity provider you can integrate with. Many of you will be familiar with the list shown by the management portal at the beginning of the add new identity provider wizard.<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/3513.image_5F00_5A0D9415.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px\" title=\"image\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/3513.image_5F00_5A0D9415.png\" width=\"488\" height=\"265\" \/><\/a><\/p>\n<p>Some of you may also know that ACS integrates with Yahoo! and Google using OpenID, however from your point of view that doesn\u2019t matter much: the details are abstracted away by ACS.<\/p>\n<p>A less-known factlet is that ACS also supports integration with other OpenId providers: however that capability is not exposed via portal, you can only set it up via management APIs. We do have a tutorial which shows you how to do that step by step using <a href=\"https:\/\/www.myopenid.com\/\">myOpenID<\/a>, you can find it <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/gg185935.aspx\">here<\/a>. <\/p>\n<p>It\u2019s not hard, that\u2019s just OData after all, but it is still<em> 6 printed pages<\/em>. Now, how would you feel if I\u2019d tell you that if you use <a href=\"http:\/\/bit.ly\/kF9ksY\">the ACS cmdlets<\/a> <strong><em><u>you can do exactly the same in ONE line of PowerShell code<\/u><\/em><\/strong>? Mind == blown, right? <img decoding=\"async\" style=\"border-bottom-style: none;border-left-style: none;border-top-style: none;border-right-style: none\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/7215.wlEmoticon_2D00_smile_5F00_39A28BFE.png\" \/>&#160;<\/p>\n<p>Here we go: <\/p>\n<blockquote>\n<p><font face=\"Courier New\">PS C:UsersvittorioDesktop&gt; <strong>Add-IdentityProvider<\/strong> \u2013Namespace \u201cmyacsnamespace\u201d \u2013ManagementKey \u201cXXXXXXXX\u201d -Type &quot;Manual&quot; -Name &quot;myOpenID&quot; -Protocol OpenId \u2013SignInAddress \u201c<\/font><a href=\"http:\/\/www.myopenid.com\/server\"><font face=\"Courier New\">http:\/\/www.myopenid.com\/server<\/font><\/a>\u201d<\/p>\n<\/blockquote>\n<p>That\u2019s it! With the \u2013Manual switch I can explicitly create any IP type. In order to maintain my boast that one line of code is enough, I used the inlined syntax for passing the namespace and the management key directly. In the <a href=\"http:\/\/bit.ly\/kF9ksY\">announcement post<\/a> I first obtained a management token with <strong><font face=\"Courier New\">Get-AcsManagementToken<\/font><\/strong>, assigned it to a variable and passed it along for all subsequent commands, which is more appropriate for longer scripts (hence from now on I\u2019ll use it instead).<\/p>\n<p>That did the equivalent of the tutorial: however, that\u2019 not enough to use myOpenID with the application yet. We still need to create rules that will add some claims or ACS won\u2019t even send a token back. Luckily, that\u2019s just another line of PowerShell code:<\/p>\n<blockquote>\n<p><font face=\"Courier New\">PS C:UsersvittorioDesktop&gt; <font color=\"#333333\"><strong>Add-Rule<\/strong><\/font> -MgmtToken $mgmtToken -GroupName &quot;Default Rule Group for myRP&quot; -IdentityProviderName &quot;myOpenID&quot;<\/font><\/p>\n<\/blockquote>\n<p>Here I didn\u2019t specify any input or output claim, which substantially ends up in a pass-through rule. NOW we\u2019re ready! Let\u2019s see what happens if I hit F5 on a plain vanilla Windows Azure webrole project where I added the SecurityTokenDisplayControl (you can find the VS2010 version in the <a href=\"http:\/\/www.microsoft.com\/downloads\/en\/details.aspx?displaylang=en&amp;FamilyID=c3e315fa-94e2-4028-99cb-904369f177c0\">identity training kit<\/a> labs about ACS).<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/5557.image_5F00_595165C6.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px\" title=\"image\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/5557.image_5F00_595165C6.png\" width=\"383\" height=\"429\" \/><\/a><\/p>\n<p>Oh hello myOpenID option! I\u2019s there, good sign. Let\u2019s hit it.<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/8765.image_5F00_37F1C02A.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-bottom: 0px;border-left: 0px;margin: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px\" title=\"image\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/8765.image_5F00_37F1C02A.png\" width=\"400\" height=\"276\" \/><\/a><\/p>\n<p>As expected, we end up on the auth page of openID. Once successfully authenticated, we get to the consent page:<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/5732.image_5F00_3CF3FDD9.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-bottom: 0px;border-left: 0px;margin: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px\" title=\"image\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/5732.image_5F00_3CF3FDD9.png\" width=\"400\" height=\"230\" \/><\/a><\/p>\n<p>Note that the consent does not mention any attributes, this fact will become relevant in a moment. Let\u2019s click continue and\u2026<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/4578.image_5F00_41F63B88.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-bottom: 0px;border-left: 0px;margin: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px\" title=\"image\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/4578.image_5F00_41F63B88.png\" width=\"500\" height=\"225\" \/><\/a><\/p>\n<p>congratulations! You just added an arbitrary OpenID provider, and all it took was just 2 lines of PowerShell (without even touching your application or opening the ACS management portal).<\/p>\n<p>Now, you may notice one thing about this transaction: we got an awfully low amount of information about the user, just the OpenID handle in fact. I am not very deep in OpenID, I\u2019ll readily admit. Luckily Oren, Chao and Andrew from the ACS team came to the rescue (thank you guys) and explained that ACS gets claims in OpenID via Attribute Exchange, which myOpenID does not support (they use <a href=\"http:\/\/egistration http:\/\/openid.net\/specs\/openid-simple-registration-extension-1_1-01.html\">Simple Registration<\/a>).<\/p>\n<p>Bummer! I really wanted to show passing name and email. Luckily adding another OpenID provider which supports AX is just a matter of hitting the up arrow a couple of times in the PowerShell ISE and change the name and signin address accordingly. In the end I settled with <a href=\"http:\/\/hyves.net\">http:\/\/hyves.net<\/a>, since <a href=\"http:\/\/bit.ly\/mHCnRp\">I was just recently in the Netherlands<\/a> <img decoding=\"async\" style=\"border-bottom-style: none;border-left-style: none;border-top-style: none;border-right-style: none\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/7215.wlEmoticon_2D00_smile_5F00_39A28BFE.png\" \/><\/p>\n<blockquote>\n<p><font face=\"Courier New\"><strong>Add-IdentityProvider<\/strong> -MgmtToken $mgmtToken -Type &quot;Manual&quot; -Name &quot;hyves.net OpenID&quot; -Protocol OpenId -SignInAddress <\/font><a href=\"https:\/\/openid.hyves-api.nl\/\"><font face=\"Courier New\">https:\/\/openid.hyves-api.nl\/<\/font><\/a><\/p>\n<p><font face=\"Courier New\"><strong>Add-Rule<\/strong> -MgmtToken $mgmtToken -GroupName &quot;Default Rule Group for myRP&quot; -IdentityProviderName &quot;hyves.net OpenID&quot;<\/font><\/p>\n<\/blockquote>\n<p>Another F5\u2026<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/8206.image_5F00_7164AA54.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-bottom: 0px;border-left: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px\" title=\"image\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/8206.image_5F00_7164AA54.png\" width=\"386\" height=\"422\" \/><\/a><\/p>\n<p>\u2026and the new option for hyves.net shows up. Good! Let\u2019s hit it.<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/4075.image_5F00_500504B8.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-bottom: 0px;border-left: 0px;margin: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px\" title=\"image\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/4075.image_5F00_500504B8.png\" width=\"400\" height=\"300\" \/><\/a><\/p>\n<p>We get to their auth page. Let\u2019s log in, we\u2019ll get to the consent page.<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/6622.image_5F00_29C2AB60.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-bottom: 0px;border-left: 0px;margin: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px\" title=\"image\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/6622.image_5F00_29C2AB60.png\" width=\"500\" height=\"342\" \/><\/a><\/p>\n<p>Now this looks more promising. Hyves.net asks permission to share the email address with the ACS endpoint, as expected. Let\u2019s grant it and see what happens.<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/1732.image_5F00_460FED80.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-bottom: 0px;border-left: 0px;margin: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px\" title=\"image\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/1732.image_5F00_460FED80.png\" width=\"550\" height=\"243\" \/><\/a><\/p>\n<p>Bingo! This time ACS (hence the RP) got the name and email claims, just like I wanted.<\/p>\n<p>Soo, let me recap. I just enabled users from two arbitrary OpenID providers to authenticate with my application; and all it took was writing two commands in the window below to provision the first provider, then modifying those two commands for provisioning the second. We are talking minutes here, and just because I am not a very good typist nor an expert in PowerShell.<\/p>\n<p><a href=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/1423.image_5F00_673FE35C.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-bottom: 0px;border-left: 0px;margin: 0px;padding-left: 0px;padding-right: 0px;border-top: 0px;border-right: 0px;padding-top: 0px\" title=\"image\" border=\"0\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/1423.image_5F00_673FE35C.png\" width=\"400\" height=\"334\" \/><\/a><\/p>\n<p>I know it\u2019s bad form that I am the one saying it: but isn\u2019t this really awesome? <img decoding=\"async\" style=\"border-bottom-style: none;border-left-style: none;border-top-style: none;border-right-style: none\" class=\"wlEmoticon wlEmoticon-winkingsmile\" alt=\"Winking smile\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/8688.wlEmoticon_2D00_winkingsmile_5F00_317A7835.png\" \/> Come on, do something with the cmdlets too! I am super-curious to see what you guys will be able to accomplish <img decoding=\"async\" style=\"border-bottom-style: none;border-left-style: none;border-top-style: none;border-right-style: none\" class=\"wlEmoticon wlEmoticon-smile\" alt=\"Smile\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2011\/05\/7215.wlEmoticon_2D00_smile_5F00_39A28BFE.png\" \/><\/p>\n<div style=\"clear:both\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>ACS offers you a variety of identity provider you can integrate with. Many of you will be familiar with the list shown by the management portal at the beginning of the add new identity provider wizard. Some of you may also know that ACS integrates with Yahoo! and Google using OpenID, however from&#8230;<\/p>\n","protected":false},"author":1,"featured_media":1349,"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":[7,8,28,49],"tags":[],"class_list":["post-318","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-access-control-service","category-acs","category-openid","category-powershell"],"_links":{"self":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/318","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=318"}],"version-history":[{"count":0,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/318\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media\/1349"}],"wp:attachment":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media?parent=318"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/categories?post=318"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/tags?post=318"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}