<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DEYHRXk6eyp7ImA9WhVWEkw.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094</id><updated>2012-04-23T14:22:14.713-07:00</updated><category term="LDIF" /><category term="SQL" /><category term="About Insight" /><category term="Exchange" /><category term="XMA" /><category term="Gadgets" /><category term="XML" /><category term="Workflow" /><category term="Encryption" /><category term="Kerberos" /><category term="MA Configuration" /><category term="SSO" /><category term="ILM" /><category term="Widgets" /><category term="Google" /><category term="SAML" /><category term="DSML" /><category term="MIIS" /><category term="PowerShell" /><category term="WMI" /><category term="XPath" /><category term="SharePoint WebParts" /><category term="FIM" /><category term="HTML" /><category term="PCNS" /><category term="Authentication" /><category term="Certificates" /><category term="About Me" /><category term="MA Rules Extensions" /><category term="About Ensynch" /><category term="signedXML" /><category term="JavaScript" /><category term="MA Join Rules" /><title>Apollo Jack</title><subtitle type="html">One developer’s foray into the realms of FIM, MOSS, Workflow, Directories, Security and anything else that happens by.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.apollojack.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.apollojack.com/" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>24</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/ApolloJack" /><feedburner:info uri="apollojack" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;A04ERH49fyp7ImA9WhVQEkk.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-2327559144643067423</id><published>2012-03-31T20:09:00.001-07:00</published><updated>2012-03-31T20:11:45.067-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-31T20:11:45.067-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Kerberos" /><category scheme="http://www.blogger.com/atom/ns#" term="MIIS" /><category scheme="http://www.blogger.com/atom/ns#" term="FIM" /><category scheme="http://www.blogger.com/atom/ns#" term="ILM" /><category scheme="http://www.blogger.com/atom/ns#" term="PCNS" /><title>FIM PCNS And A Lack of Trust</title><content type="html">&lt;p&gt;If you read through the FIM documentation for setting up PCNS, you will find that either FIM and PCNS need to be in the same forest or be part of a forest trust. From &lt;a title="http://technet.microsoft.com/en-us/library/cc720594(v=ws.10).aspx" href="http://technet.microsoft.com/en-us/library/cc720594(v=ws.10).aspx"&gt;http://technet.microsoft.com/en-us/library/cc720594(v=ws.10).aspx&lt;/a&gt;:&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="90%"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="36"&gt;&amp;#160;&lt;/td&gt;        &lt;td bgcolor="#c0c0c0" valign="top"&gt;         &lt;p&gt;&lt;font size="2" face="Garamond"&gt;Forest trusts are only required if PCNS and ILM 2007 are located in different forests. If this is the case, a forest-level trust must be established. This is required for Kerberos mutual authentication for the ILM 2007 server to accept the request from a remote forest host.&lt;/font&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;This can become extremely limiting, especially if both forests do not have the proper forest and domain levels.&amp;#160; Theoretically, however, it’s possible to make Kerberos work over an External Trust (&lt;a title="http://blogs.technet.com/b/activedirectoryua/archive/2010/08/04/conditions-for-kerberos-to-be-used-over-an-external-trust.aspx" href="http://blogs.technet.com/b/activedirectoryua/archive/2010/08/04/conditions-for-kerberos-to-be-used-over-an-external-trust.aspx"&gt;http://blogs.technet.com/b/activedirectoryua/archive/2010/08/04/conditions-for-kerberos-to-be-used-over-an-external-trust.aspx&lt;/a&gt;).&amp;#160; With an External Trust, we don’t have any of the same forest functional level restrictions, opening up PCNS as a viable option for more customers.&amp;#160; I would love to know if anyone has been able to get PCNS working in this configuration.&amp;#160; In the mean time, I will have to set up a lab and try it out.&amp;#160; I will report back on the results and let you know! &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-2327559144643067423?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/4gUvUFVV_AA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/2327559144643067423/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=2327559144643067423&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/2327559144643067423?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/2327559144643067423?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/4gUvUFVV_AA/fim-pcns-and-lack-of-trust.html" title="FIM PCNS And A Lack of Trust" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.apollojack.com/2012/03/fim-pcns-and-lack-of-trust.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQMQ309fip7ImA9WhVTEUw.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-273058196880666657</id><published>2012-02-24T13:19:00.000-08:00</published><updated>2012-02-24T13:19:42.366-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-24T13:19:42.366-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="FIM" /><category scheme="http://www.blogger.com/atom/ns#" term="Workflow" /><title>The Last FIM Workflow You Will Ever Need</title><content type="html">&lt;p&gt;Okay, probably not, but its still pretty cool.&amp;#160; I recently built a Workflow in FIM that will allow a user to define the code they want executed at run time.&amp;#160; The Workflow will compile the code and run it in a separate app domain when its initiated (&lt;a title="http://www.west-wind.com//presentations/dynamicCode/DynamicCode.htm" href="http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm"&gt;http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm&lt;/a&gt;).&amp;#160; The UI will allow you to specify the input parameters and where the result of the code execution will go.&amp;#160; Here is a simple example, I am passing in the first and last name from the target of the request, I am also passing the the mail host that I have calculated in a previous step and saved to WorkflowData.&amp;#160; I am then using the code to calculate the user’s email address and save it to the email parameter on the target:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh5.ggpht.com/-gudFHETMPLU/Tz1_XPSPJfI/AAAAAAAAAMQ/cUPbCUHkoBI/s1600-h/image%25255B35%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-VyIJzZeKj08/Tz1_Y3Dh8yI/AAAAAAAAAMU/JPVYhdk49iM/image_thumb%25255B47%25255D.png?imgmax=800" width="640" height="367" /&gt;&lt;/a&gt;&lt;a href="http://lh4.ggpht.com/-qeINh_n_vSQ/Tz1_ZuCIsKI/AAAAAAAAAMY/yglo0eH-rcM/s1600-h/image%25255B36%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-p0xNn85F7b0/Tz1_aCBjk-I/AAAAAAAAAMc/fb3ThBNHk7U/image_thumb%25255B48%25255D.png?imgmax=800" width="640" height="379" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;You can add and remove input parameters as needed during design time and then refer to them in the code using their specified index. I expect in future releases to be allow the user to specify additional namespaces and code references to import. It currently won’t do any syntax checking or formatting at design time, but otherwise its extremely versatile and flexible!&amp;#160; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-273058196880666657?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/gLT06_NFdQg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/273058196880666657/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=273058196880666657&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/273058196880666657?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/273058196880666657?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/gLT06_NFdQg/last-fim-workflow-you-will-ever-need.html" title="The Last FIM Workflow You Will Ever Need" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-VyIJzZeKj08/Tz1_Y3Dh8yI/AAAAAAAAAMU/JPVYhdk49iM/s72-c/image_thumb%25255B47%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.apollojack.com/2012/02/last-fim-workflow-you-will-ever-need.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQEQ34zfSp7ImA9WhVTEUw.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-7031745999373901266</id><published>2012-01-13T09:34:00.002-08:00</published><updated>2012-02-24T13:18:22.085-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-24T13:18:22.085-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MA Configuration" /><category scheme="http://www.blogger.com/atom/ns#" term="FIM" /><category scheme="http://www.blogger.com/atom/ns#" term="DSML" /><category scheme="http://www.blogger.com/atom/ns#" term="SQL" /><title>Sun One Boolean Attributes</title><content type="html">&lt;p&gt;Recently while working with the Sun One MA, I came across a problem caused by how FIM interprets boolean data coming from the directory.&amp;#160; In this case, the Sun One directory stores its boolean data as “YES” or “NO”, however when imported by FIM, this data always gets converted to False in the connector space.&amp;#160; (&lt;a title="http://social.technet.microsoft.com/Forums/en-US/identitylifecyclemanager/thread/8ffc112e-d945-4916-83b3-78fbba716705" href="http://social.technet.microsoft.com/Forums/en-US/identitylifecyclemanager/thread/8ffc112e-d945-4916-83b3-78fbba716705"&gt;http://social.technet.microsoft.com/Forums/en-US/identitylifecyclemanager/thread/8ffc112e-d945-4916-83b3-78fbba716705&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;Now we can’t use an advance import flow to correctly convert the data as it comes into the Metaverse because we have already lost data integrity.&amp;#160; The data that’s in the connector space is basically useless.&amp;#160; This only leaves us with a couple of options, we can write an XMA to correctly handle the data, but this can be fairly complicated.&amp;#160; We can also update the directory schema and use a string instead of a boolean, however, this could cause other downstream issues with other systems that might be consuming this data.&amp;#160; There is one other option, but its completely unsupported.&amp;#160; You could update the FIM database to make the system think this attribute is a string.&amp;#160; &lt;/p&gt;&lt;p&gt;Begin by running the following SQL Statement using the SQL Server Management Studio against your FIM database:&lt;/p&gt;&lt;blockquote style="border-bottom: #7ba0cd 1px solid; border-left: #7ba0cd 1px solid; padding-bottom: 10px; padding-left: 5px; padding-right: 5px; background: #d3dfee; border-top: #7ba0cd 1px solid; border-right: #7ba0cd 1px solid; padding-top: 10px"&gt;&lt;font size="2" face="Consolas"&gt;SELECT CAST(ma_schema_xml AS XML)&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;
&amp;#160; FROM FIMSynchronizationService.dbo.mms_management_agent       &lt;br /&gt;
&amp;#160;WHERE ma_name = '&amp;lt;Sun One MA Name Here&amp;gt;'&lt;/font&gt;&lt;/blockquote&gt;&lt;p&gt;In the results window you will get a single record that can be clicked on to open an xml document containing the schema for your Sun MA. Each attribute in the directory will appear using this syntax: &lt;/p&gt;&lt;p&gt;&lt;blockquote style="border-bottom: #7ba0cd 1px solid; border-left: #7ba0cd 1px solid; padding-bottom: 10px; padding-left: 5px; padding-right: 5px; background: #d3dfee; border-top: #7ba0cd 1px solid; border-right: #7ba0cd 1px solid; padding-top: 10px"&gt;&lt;font size="2" face="Consolas"&gt;&amp;lt;attribute-type id=&amp;quot;system_assigned_id&amp;quot; single-value=&amp;quot;true/false&amp;quot;&amp;gt;      &lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;name&amp;gt;attribute_name&amp;lt;/name&amp;gt;       &lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;syntax&amp;gt;LDAPv3_syntax_oid&amp;lt;/syntax&amp;gt;       &lt;br /&gt;
&amp;lt;/attribute-type&amp;gt;&lt;/font&gt;&lt;/blockquote&gt;&lt;/p&gt;&lt;p&gt;If you do a quick search (Ctrl+F) for your attribute, you can manually update the &lt;a href="http://www.alvestrand.no/objectid/1.3.6.1.4.1.1466.115.121.1.html" target="_blank"&gt;LDAP Syntax OID&lt;/a&gt; from a boolean (&lt;a href="http://www.alvestrand.no/objectid/1.3.6.1.4.1.1466.115.121.1.7.html"&gt;1.3.6.1.4.1.1466.115.121.1.7&lt;/a&gt;) to a string (&lt;a href="http://www.alvestrand.no/objectid/1.3.6.1.4.1.1466.115.121.1.15.html"&gt;1.3.6.1.4.1.1466.115.121.1.15&lt;/a&gt;).&amp;#160; In my case, the new XML looked like:&lt;/p&gt;&lt;p&gt;&lt;blockquote style="border-bottom: #7ba0cd 1px solid; border-left: #7ba0cd 1px solid; padding-bottom: 10px; padding-left: 5px; padding-right: 5px; background: #d3dfee; border-top: #7ba0cd 1px solid; border-right: #7ba0cd 1px solid; padding-top: 10px"&gt;&lt;font size="2" face="Consolas"&gt;&amp;lt;attribute-type id=&amp;quot;Ah&amp;quot; single-value=&amp;quot;true&amp;quot;&amp;gt;      &lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;name&amp;gt;isManager&amp;lt;/name&amp;gt;       &lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;syntax&amp;gt;1.3.6.1.4.1.1466.115.121.1.15&amp;lt;/syntax&amp;gt;       &lt;br /&gt;
&amp;lt;/attribute-type&amp;gt;&lt;/font&gt;&lt;/blockquote&gt;&lt;/p&gt;&lt;p&gt;I then used an update statement to write this information back to the database.&amp;#160; After performing a full import on this MA the connector space now reflected this data as a string of “YES” or “NO” just as it appears in the directory.&amp;#160; Now that the connector space had data I could work with, I wrote a quick advanced import flow rule to transform this value to a boolean:&lt;/p&gt;&lt;p&gt;&lt;blockquote style="border-bottom: #7ba0cd 1px solid; border-left: #7ba0cd 1px solid; padding-bottom: 10px; padding-left: 5px; padding-right: 5px; background: #d3dfee; border-top: #7ba0cd 1px solid; border-right: #7ba0cd 1px solid; padding-top: 10px"&gt;&lt;font size="2" face="Consolas"&gt;case &amp;quot;isManager&amp;quot;:      &lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160; //perform conversion for isManager from yes/no to boolean value       &lt;br /&gt;
&amp;#160;&amp;#160; if (csentry[&amp;quot;isManager&amp;quot;].IsPresent)       &lt;br /&gt;
&amp;#160;&amp;#160; {       &lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (csentry[&amp;quot;isManager&amp;quot;].Value.Equals(&amp;quot;yes&amp;quot;, StringComparison.InvariantCultureIgnoreCase))       &lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mventry[&amp;quot;isManager&amp;quot;].BooleanValue = true;       &lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; else       &lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {       &lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; mventry[&amp;quot;isManager&amp;quot;].BooleanValue = false;       &lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }       &lt;br /&gt;
&amp;#160;&amp;#160; }       &lt;br /&gt;
&amp;#160;&amp;#160; break;&lt;/font&gt;&lt;/blockquote&gt;&lt;/p&gt;&lt;p&gt;This approach does have its risks.&amp;#160; It will need to be re-done after performing a schema refresh in FIM and there is no guarantee it will keep working after an upgrade/patch.&amp;#160;&amp;#160; The following SQL query could be used to script out this update, just replace the attributeName and SunOneMA variables and you should be good to go:&lt;/p&gt;&lt;p&gt;&lt;blockquote style="border-bottom: #7ba0cd 1px solid; border-left: #7ba0cd 1px solid; padding-bottom: 10px; padding-left: 5px; padding-right: 5px; background: #d3dfee; border-top: #7ba0cd 1px solid; border-right: #7ba0cd 1px solid; padding-top: 10px"&gt;&lt;font size="2" face="Consolas"&gt;DECLARE @attributeName AS Varchar(255) = '&amp;lt;Attribute Name Here&amp;gt;'      &lt;br /&gt;
DECLARE @SunOneMA AS Varchar(255) = '&amp;lt;Sun One MA Name Here&amp;gt;'       &lt;br /&gt;
DECLARE @newSchemaOID AS Varchar(255) = '1.3.6.1.4.1.1466.115.121.1.15' --Directory String       &lt;br /&gt;
&lt;br /&gt;
-- get schema data       &lt;br /&gt;
DECLARE @schema AS XML       &lt;br /&gt;
&lt;br /&gt;
SELECT @schema = CAST(ma_schema_xml as xml)       &lt;br /&gt;
&amp;#160; FROM FIMSynchronizationService.dbo.mms_management_agent       &lt;br /&gt;
&amp;#160;WHERE ma_name = @SunOneMA       &lt;br /&gt;
&lt;br /&gt;
-- update schema type       &lt;br /&gt;
SET @schema.modify('       &lt;br /&gt;
&amp;#160;&amp;#160; declare default element namespace http://www.dsml.org/DSML;      &lt;br /&gt;
&amp;#160;&amp;#160; replace value of       &lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (dsml/directory-schema/attribute-type[name=sql:variable(&amp;quot;@attributeName&amp;quot;)]/syntax/text())[1]       &lt;br /&gt;
&amp;#160;&amp;#160; with       &lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; sql:variable(&amp;quot;@newSchemaOID&amp;quot;)       &lt;br /&gt;
&amp;#160;&amp;#160; ')       &lt;br /&gt;
&lt;br /&gt;
-- save back to table       &lt;br /&gt;
UPDATE FIMSynchronizationService.dbo.mms_management_agent       &lt;br /&gt;
&amp;#160;&amp;#160; SET ma_schema_xml = CONVERT(nvarchar(MAX), @schema)       &lt;br /&gt;
&amp;#160;WHERE ma_name = @SunOneMA&lt;/font&gt;&lt;/blockquote&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-7031745999373901266?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/EjZWbll6r6g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/7031745999373901266/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=7031745999373901266&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/7031745999373901266?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/7031745999373901266?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/EjZWbll6r6g/sun-one-boolean-attributes.html" title="Sun One Boolean Attributes" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.apollojack.com/2012/01/sun-one-boolean-attributes.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcBR344fSp7ImA9WhdVFUk.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-2678246671444966174</id><published>2011-09-20T11:16:00.001-07:00</published><updated>2011-09-20T11:40:56.035-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-20T11:40:56.035-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="About Insight" /><category scheme="http://www.blogger.com/atom/ns#" term="About Me" /><category scheme="http://www.blogger.com/atom/ns#" term="About Ensynch" /><title>Ensynch Joins Insight!</title><content type="html">&lt;p&gt;We are very excited about the union of Insight and Ensynch and the benefits that it will bring to our clients. Both companies are focused on helping our clients find innovative, cost effective solutions to address business needs. Bringing Ensynch into the Insight organization will offer clients more robust software services, particularly around Microsoft Enterprise Agreements, as well as improved services delivery, enhanced virtualization and cloud capabilities and solution-focused approach to software sales. This acquisition will further simplify our clients’ ability to acquire, procure, implement and manage IT solutions across their technology environment.&lt;/p&gt;&lt;p&gt;For more information, read the press release &lt;a href="http://www.ensynch.com/Lists/Announcements/BrandedDisplay.aspx?ID=34"&gt;here&lt;/a&gt;, visit &lt;a href="http://www.insight.com"&gt;www.insight.com&lt;/a&gt; or &lt;a href="http://www.ensynch.com"&gt;www.ensynch.com&lt;/a&gt;, or contact me with any questions.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-2678246671444966174?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/Z-ADtRpozDY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/2678246671444966174/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=2678246671444966174&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/2678246671444966174?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/2678246671444966174?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/Z-ADtRpozDY/ensynch-joins-insight.html" title="Ensynch Joins Insight!" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.apollojack.com/2011/09/ensynch-joins-insight.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UDSH4yfSp7ImA9WhRVFEo.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-5166433406573533372</id><published>2011-07-27T12:47:00.001-07:00</published><updated>2012-01-13T10:27:59.095-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-13T10:27:59.095-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="FIM" /><category scheme="http://www.blogger.com/atom/ns#" term="LDIF" /><category scheme="http://www.blogger.com/atom/ns#" term="XMA" /><title>FIM 2010 and Language Types</title><content type="html">&lt;p&gt;Recently, while working with &lt;a href="http://www.boothbilt.com/blog/" target="_blank"&gt;James&lt;/a&gt; we had to support synchronization of identity data that used language types/codes.&amp;#160;&amp;#160; Here’s a little background…&lt;/p&gt;&lt;p&gt;Directories that support &lt;a href="http://tools.ietf.org/html/rfc3866" target="_blank"&gt;RFC 3866&lt;/a&gt; (in this case Sun One) allow you to specify the language of an attribute’s value.&amp;#160; Here’s a simple example, say your company has a presence in the States and in Germany and you want to be able to store the user’s title “Software products” in both English and German, you can do that like this:&lt;/p&gt;&lt;p&gt;title;lang-en: Software products    &lt;br /&gt;
title;lang-de: Softwareprodukte &lt;/p&gt;&lt;p&gt;Now, FIM will support reading these attributes out of the directory and storing them into the CS, up to a point.&amp;#160; If you were to import this attribute, what you would get is a single multi-valued title attribute with both values, at which point you have lost all of the language information:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh4.ggpht.com/-NI4DWK0TkSY/TjBrQdyyAEI/AAAAAAAAAKc/NrDRtbPYbs4/s1600-h/image%25255B14%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="XMA Import" border="0" alt="XMA Import" src="http://lh4.ggpht.com/-3is0dgvDt2M/TjBrRDffW7I/AAAAAAAAAKg/ccAsAxQMhGY/image_thumb%25255B19%25255D.png?imgmax=800" width="719" height="565" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
In order to preserve this information, we ended up writing our own XMA to bring in the attribute with its language type as an attribute in its own right.&amp;#160; So using the DirectoryServices (or DirectoryServices.Protocols, if you prefer) namespace we were able to access the directory and retrieve the full name of the attribute, we then wrote this out to our file so that FIM would see them as different items. (If you end up writing your XMA using the LDIF file format, like we did, you will have to actually transform the attribute name on the way out to the file to remove/replace the “;” or you will continue to have the issue above!)&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh3.ggpht.com/-18b-JCMF2aQ/TjBrRnkYxLI/AAAAAAAAAKk/EG1oZbDZa2E/s1600-h/image%25255B21%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="XMA with Language Code Support" border="0" alt="XMA with Language Code Support" src="http://lh6.ggpht.com/-9QQ9VAUlTzQ/TjBrSB7lnoI/AAAAAAAAAKo/JR_PHSo6lq8/image_thumb%25255B29%25255D.png?imgmax=800" width="723" height="614" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
We can now flow these attributes with the language information intact to other downstream systems.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-5166433406573533372?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/GKCax06JwKI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/5166433406573533372/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=5166433406573533372&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/5166433406573533372?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/5166433406573533372?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/GKCax06JwKI/fim-2010-and-language-types.html" title="FIM 2010 and Language Types" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-3is0dgvDt2M/TjBrRDffW7I/AAAAAAAAAKg/ccAsAxQMhGY/s72-c/image_thumb%25255B19%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.apollojack.com/2011/07/fim-2010-and-language-types.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUAGQXs8eCp7ImA9WhdSF08.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-5812247445551005628</id><published>2011-07-26T15:49:00.001-07:00</published><updated>2011-07-26T17:48:40.570-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-26T17:48:40.570-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="FIM" /><category scheme="http://www.blogger.com/atom/ns#" term="XMA" /><title>XMA Creation Feature</title><content type="html">&lt;p&gt;So recently while creating some XMAs for FIM 2010 I noticed that while the initial creation page looked like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-4uL9pMcFfi0/Ti9EhEt5e_I/AAAAAAAAAKM/xWDya_mtvdQ/s1600-h/image001%25255B30%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="XMA Initial Creation" border="0" alt="XMA Initial Creation" src="http://lh5.ggpht.com/-dl56XYHGXoM/Ti9EhSpAqvI/AAAAAAAAAKQ/U-Ul2nvumJg/image001_thumb%25255B28%25255D.png?imgmax=800" width="541" height="404" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;When I opened the XMA after it was created I got:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-qGVx7bSKm68/Ti9EhrpfeQI/AAAAAAAAAKU/rJCzXhYaIHE/s1600-h/image003%25255B5%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="XMA After Creation" border="0" alt="XMA After Creation" src="http://lh6.ggpht.com/-Qa0CHO_PqBo/Ti9Eh1ZbCTI/AAAAAAAAAKY/POhQCUDWMKI/image003_thumb%25255B3%25255D.png?imgmax=800" width="541" height="413" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;“One of these things is not like the others….”&amp;#160; Even though I didn’t select the checkbox for the “Run this management agent in a separate process” option, the FIM Sync Engine created it that way.&amp;#160; It will remember the setting from this point in, but if you forget, this can make attaching the debugger and stepping into your code a little more difficult.&amp;#160; (Just as any FYI, I usually do turn this feature on when I am running the XMA in a QA/Production environment to minimize the chance that I could bring done the main sync miiserver process).&amp;#160; This only appears to be an issue the XMA, I haven’t noticed this issue with any of the other MA types.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-5812247445551005628?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/XKnEmGZ767M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/5812247445551005628/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=5812247445551005628&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/5812247445551005628?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/5812247445551005628?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/XKnEmGZ767M/xma-creation-feature.html" title="XMA Creation Feature" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-dl56XYHGXoM/Ti9EhSpAqvI/AAAAAAAAAKQ/U-Ul2nvumJg/s72-c/image001_thumb%25255B28%25255D.png?imgmax=800" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://www.apollojack.com/2011/07/xma-creation-feature.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QHRH04eip7ImA9WhZbEUs.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-7912336760614290185</id><published>2011-06-15T12:13:00.001-07:00</published><updated>2011-06-15T12:15:35.332-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-15T12:15:35.332-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="FIM" /><category scheme="http://www.blogger.com/atom/ns#" term="Workflow" /><category scheme="http://www.blogger.com/atom/ns#" term="PowerShell" /><category scheme="http://www.blogger.com/atom/ns#" term="Exchange" /><title>Exchange Room Resources</title><content type="html">&lt;p&gt;Recently while trying to provision Room Resource Mailboxes via FIM, or more specifically I was setting their Access Booking Policies via the Set-CalendarProcessing command in a PowerShell Workflow, I received the following error:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#ff0000"&gt;The values for ResourceMake, ResourceModel, and ResourceType must be included in the ResourceProperties collection.&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You may also see this error if you try to open the object in the Exchange Management Console and try to save it.&amp;#160; &lt;/p&gt;  &lt;p&gt;Upon further inspection, the issue appeared because the msExchResourceSearchProperties attribute didn’t contain the resource type, in this case “Room”, anywhere in the multi-valued list.&amp;#160; After manually adding this value to the existing list, this issue was resolved.&amp;#160; Since we are getting this list from user input in the portal, a more permanent solution will involve adding a Workflow to ensure that “Room” appears in this list when we add/update it in the portal.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-7912336760614290185?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/5rZNIRQ6rCM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/7912336760614290185/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=7912336760614290185&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/7912336760614290185?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/7912336760614290185?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/5rZNIRQ6rCM/exchange-room-resources.html" title="Exchange Room Resources" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.apollojack.com/2011/06/exchange-room-resources.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UGQXszcCp7ImA9WhRVFEo.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-1239225346176170016</id><published>2011-05-26T09:29:00.001-07:00</published><updated>2012-01-13T10:27:00.588-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-13T10:27:00.588-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="XPath" /><category scheme="http://www.blogger.com/atom/ns#" term="MIIS" /><category scheme="http://www.blogger.com/atom/ns#" term="FIM" /><category scheme="http://www.blogger.com/atom/ns#" term="XML" /><category scheme="http://www.blogger.com/atom/ns#" term="SQL" /><category scheme="http://www.blogger.com/atom/ns#" term="LDIF" /><category scheme="http://www.blogger.com/atom/ns#" term="ILM" /><category scheme="http://www.blogger.com/atom/ns#" term="XMA" /><title>TEC 2011</title><content type="html">&lt;p&gt;For those of you who were able to make it to my presentation at TEC 2011 (State side), I promised a blog entry going into some more technical detail on the Ensynch Accelerated SQL XMA (coming soon).&amp;#160; If you are interested in the slides I presented you can get them &lt;a href="http://cid-3a8dcbe427b2ccee.office.live.com/view.aspx/Public/Ensynch%20Accelerated%20SQL%20XMA.pptx" target="_blank"&gt;here&lt;/a&gt;.&amp;#160; Jeremy also had another suggestion that I will be trying out, so keep an eye out, I will let you know how it goes!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-1239225346176170016?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/yHHbCVqVn2U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/1239225346176170016/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=1239225346176170016&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/1239225346176170016?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/1239225346176170016?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/yHHbCVqVn2U/tec-2011.html" title="TEC 2011" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.apollojack.com/2011/05/tec-2011.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MHQ3s6eSp7ImA9WhRVFEo.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-6642770890340334044</id><published>2011-05-25T17:15:00.001-07:00</published><updated>2012-01-13T10:30:32.511-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-13T10:30:32.511-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="FIM" /><title>Custom Attributes in a Function Evaluator Workflow Activity (or lack there of)</title><content type="html">&lt;p&gt;Okay, so &lt;a href="http://social.technet.microsoft.com/Forums/en-US/ilm2/thread/eec8e249-fe28-45d5-8234-16a05104ec8b" target="_blank"&gt;as some of you have found out&lt;/a&gt; if you bind a custom attribute to a custom resource in FIM, those attributes don’t show up in the Function Evaluator Workflow Activity drop-downs here:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://lh5.ggpht.com/-cUEHpcLMJ7g/Td2bsey-wWI/AAAAAAAAAFM/NQbcB1LP-UE/s1600-h/image%25255B18%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-rht3rTyTKdc/Td2bsgghE8I/AAAAAAAAAFQ/K30Q0Wj7PF4/image_thumb%25255B21%25255D.png?imgmax=800" width="457" height="314" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;or here:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-pLT9Bk6zqZE/Td2btOEGgAI/AAAAAAAAAFU/JfshzWVcSlQ/s1600-h/image%25255B17%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-0DCdhsMh--0/Td2btW7TQfI/AAAAAAAAAFY/woiKmCSoD_U/image_thumb%25255B20%25255D.png?imgmax=800" width="463" height="306" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;There are two ways to go about fixing this, you can bind the custom property to a “known” resource type, like user.&amp;#160; Or you can skip the lookup and go ahead and reference them anyway using the CustomExpression option.&amp;#160; This will mean hand typing the attribute name into the Destination and Custom Expression fields, but it will keep your bindings cleaner:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-p0Ow7Er5kYQ/Td2bt6REbpI/AAAAAAAAAFc/t1rRQ76V_Ms/s1600-h/image%25255B26%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-Kh2E0sVT1S8/Td2buE-P66I/AAAAAAAAAFg/5CxsWvZ4JyY/image_thumb%25255B32%25255D.png?imgmax=800" width="470" height="234" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-6642770890340334044?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/v0A5McFUqAU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/6642770890340334044/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=6642770890340334044&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/6642770890340334044?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/6642770890340334044?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/v0A5McFUqAU/custom-attributes-in-function-evaluator.html" title="Custom Attributes in a Function Evaluator Workflow Activity (or lack there of)" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-rht3rTyTKdc/Td2bsgghE8I/AAAAAAAAAFQ/K30Q0Wj7PF4/s72-c/image_thumb%25255B21%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.apollojack.com/2011/05/custom-attributes-in-function-evaluator.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck4BR3g_cCp7ImA9WhZQFU4.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-2609293061672422233</id><published>2011-04-22T17:01:00.001-07:00</published><updated>2011-04-22T20:55:56.648-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-22T20:55:56.648-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MA Configuration" /><category scheme="http://www.blogger.com/atom/ns#" term="MIIS" /><category scheme="http://www.blogger.com/atom/ns#" term="FIM" /><category scheme="http://www.blogger.com/atom/ns#" term="DSML" /><category scheme="http://www.blogger.com/atom/ns#" term="XML" /><category scheme="http://www.blogger.com/atom/ns#" term="LDIF" /><category scheme="http://www.blogger.com/atom/ns#" term="ILM" /><category scheme="http://www.blogger.com/atom/ns#" term="XMA" /><title>File Based Management Agents In MIIS/ILM/FIM</title><content type="html">&lt;span xmlns="xmlns"&gt;   &lt;p&gt;&lt;span style="font-family: times new roman; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;I had a recent need to really compare the capabilities of each of the file based Management Agents in FIM.&amp;#160; Can you name all five? Don't worry, I won't leave you hanging, they are:          &lt;br /&gt;
&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;font size="2"&gt;Attribute-value pair text file &lt;/font&gt;&lt;/li&gt;
&lt;li&gt;&lt;font size="2"&gt;Delimited text file &lt;/font&gt;&lt;/li&gt;
&lt;li&gt;&lt;font size="2"&gt;Directory Services Markup Language (DSML) 2.0 &lt;/font&gt;&lt;/li&gt;
&lt;li&gt;&lt;font size="2"&gt;Fixed-width text file &lt;/font&gt;&lt;/li&gt;
&lt;li&gt;&lt;font size="2"&gt;LDAP Data Interchange Format (LDIF) &lt;/font&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;span style="font-family: times new roman; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;Here are some of the things that they can and can't do (this is for you &lt;a href="http://c--shark.blogspot.com/"&gt;Joe&lt;/a&gt;) and just for kicks, I also added in the SQL MA.  If you are using one of these file types in an Extensible Management Agent (XMA), the following still applies:&amp;#160; &lt;br /&gt;
&lt;br /&gt;
&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;table style="border-collapse: collapse" border="0" width="80%"&gt;&lt;colgroup&gt;&lt;font face="Georgia"&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/font&gt;&lt;/colgroup&gt;&lt;tbody valign="top"&gt;
&lt;tr style="background: #b8cce4"&gt;           &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px"&gt;&lt;font size="2" face="Georgia"&gt;&amp;#160;&lt;/font&gt;&lt;/td&gt;            &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;strong&gt;&lt;font size="2" face="Georgia"&gt;Multi-valued Attributes&lt;/font&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;strong&gt;&lt;font face="Georgia"&gt;&lt;font size="2"&gt;Attribute Level Updates &lt;sup&gt;1&lt;/sup&gt;&lt;/font&gt;&lt;/font&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;strong&gt;&lt;font face="Georgia"&gt;&lt;font size="2"&gt;Multi-valued Level Attribute Updates &lt;sup&gt;2&lt;/sup&gt;&lt;/font&gt;&lt;/font&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #365f91" nowrap="nowrap"&gt;             &lt;p&gt;&lt;span style="font-family: times new roman; color: white; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;Attribute-value pair&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #a7bfde"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;YES&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #a7bfde"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;NO&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #a7bfde"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;NO&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #365f91"&gt;             &lt;p&gt;&lt;span style="font-family: times new roman; color: white; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;Delimited&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #dbe5f1"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;font face="Georgia"&gt;&lt;font size="2"&gt;YES &lt;sup&gt;3&lt;/sup&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #dbe5f1"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;NO&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #dbe5f1"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;NO&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #365f91"&gt;             &lt;p&gt;&lt;span style="font-family: times new roman; color: white; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;DSML&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #a7bfde"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;YES&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #a7bfde"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;font face="Georgia"&gt;&lt;font size="2"&gt;NO &lt;sup&gt;4&lt;/sup&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #a7bfde"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;NO&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #365f91"&gt;             &lt;p&gt;&lt;span style="font-family: times new roman; color: white; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;Fixed-width&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #dbe5f1"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;font face="Georgia"&gt;&lt;font size="2"&gt;YES &lt;sup&gt;3&lt;/sup&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #dbe5f1"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;NO&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #dbe5f1"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;NO&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #365f91"&gt;             &lt;p&gt;&lt;span style="font-family: times new roman; color: white; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;LDIF&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #a7bfde"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;YES&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #a7bfde"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;YES&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="border-bottom: white 0.5pt solid; padding-left: 7px; padding-right: 7px; border-top-style: none; background: #a7bfde"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;ON IMPORT ONLY&lt;sup&gt; 5&lt;/sup&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td style="padding-left: 7px; padding-right: 7px; border-top-style: none; background: #365f91"&gt;             &lt;p&gt;&lt;span style="font-family: times new roman; color: white; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;SQL MA&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="padding-left: 7px; padding-right: 7px; border-top-style: none; background: #dbe5f1"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;YES&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="padding-left: 7px; padding-right: 7px; border-top-style: none; background: #dbe5f1"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;font size="2" face="Georgia"&gt;YES&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;            &lt;td style="padding-left: 7px; padding-right: 7px; border-top-style: none; background: #dbe5f1"&gt;             &lt;p style="text-align: center"&gt;&lt;span style="font-family: times new roman; color: black; font-size: 12pt"&gt;&lt;font face="Georgia"&gt;&lt;font size="2"&gt;NO &lt;sup&gt;6&lt;/sup&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;         &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;/span&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;font size="2"&gt;Okay, now for the caveats (can’t get away without some of those):&lt;/font&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;font size="2"&gt;An Attribute Level Update implies that a delta import can contain only the attribute that has changed (along with the other required columns, like the type of change and the anchor)&lt;/font&gt;       &lt;br /&gt;
&lt;br /&gt;
So, here’s what that might look like.&amp;#160; Suppose I have a user with the following attributes:       &lt;br /&gt;
&lt;table border="0" cellspacing="2" cellpadding="2" width="501"&gt;&lt;tbody&gt;
&lt;tr&gt;           &lt;td valign="top" width="128"&gt;&amp;nbsp;&lt;/td&gt;            &lt;td valign="top" width="171" align="right"&gt;             ID:           &lt;/td&gt;            &lt;td valign="top" width="192"&gt;12345 &lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td valign="top" width="128"&gt;&amp;nbsp;&lt;/td&gt;            &lt;td valign="top" width="171" align="right"&gt;             Name:           &lt;/td&gt;            &lt;td valign="top" width="192"&gt;Sarah &lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td valign="top" width="128"&gt;&amp;nbsp;&lt;/td&gt;            &lt;td valign="top" width="171" align="right"&gt;             Status:           &lt;/td&gt;            &lt;td valign="top" width="192"&gt;Active &lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td valign="top" width="128"&gt;&amp;nbsp;&lt;/td&gt;            &lt;td valign="top" width="171" align="right"&gt;             Phone:           &lt;/td&gt;            &lt;td valign="top" width="192"&gt;555-123-4567&lt;/td&gt;         &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;
If Sarah’s phone number changes to 555-987-6543, I can simply tell FIM something like:&amp;#160; &lt;table border="0" cellspacing="2" cellpadding="2" width="499"&gt;&lt;tbody&gt;
&lt;tr&gt;           &lt;td valign="top" width="128"&gt;&amp;#160;&lt;/td&gt;            &lt;td valign="top" width="167" align="right"&gt;             ID:           &lt;/td&gt;            &lt;td valign="top" width="194"&gt;12345&amp;#160; &lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td valign="top" width="128"&gt;&amp;#160;&lt;/td&gt;            &lt;td valign="top" width="167" align="right"&gt;             Type Of Change:           &lt;/td&gt;            &lt;td valign="top" width="194"&gt;Update&lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td valign="top" width="128"&gt;&amp;#160;&lt;/td&gt;            &lt;td valign="top" width="167" align="right"&gt;            Phone:           &lt;/td&gt;            &lt;td valign="top" width="194"&gt;555-987-6543&lt;/td&gt;         &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
This has the advantage of giving FIM less work to do to determine what has changed on the records being imported and greatly speeds up delta imports.&amp;#160; &lt;br /&gt;
&amp;#160; &lt;/li&gt;
&lt;li&gt;&lt;font size="2"&gt;A Multi-valued Level Attribute Update supports adding and deleting specific values from a multi-valued attribute        &lt;br /&gt;
&lt;/font&gt;&amp;#160; &lt;br /&gt;
Let’s take another look at Sara’s record:       &lt;br /&gt;
&lt;table border="0" cellspacing="2" cellpadding="2" width="505"&gt;&lt;tbody&gt;
&lt;tr&gt;           &lt;td valign="top" width="128"&gt;&amp;#160;&lt;/td&gt;            &lt;td valign="top" width="168" align="right"&gt;             ID:           &lt;/td&gt;            &lt;td valign="top" width="199"&gt;12345&amp;#160; &lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td valign="top" width="128"&gt;&amp;#160;&lt;/td&gt;            &lt;td valign="top" width="168" align="right"&gt;             Name:           &lt;/td&gt;            &lt;td valign="top" width="199"&gt;Sarah&amp;#160; &lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td valign="top" width="128"&gt;&amp;#160;&lt;/td&gt;            &lt;td valign="top" width="168" align="right"&gt;             Status:           &lt;/td&gt;            &lt;td valign="top" width="199"&gt;Active&amp;#160; &lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td valign="top" width="128"&gt;&amp;#160;&lt;/td&gt;            &lt;td valign="top" width="168" align="right"&gt;             Phone:           &lt;/td&gt;            &lt;td valign="top" width="199"&gt;555-123-4567 &lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td valign="top" width="128"&gt;&amp;#160;&lt;/td&gt;            &lt;td valign="top" width="168" align="right"&gt;             Phone:           &lt;/td&gt;            &lt;td valign="top" width="199"&gt;555-456-7890&lt;/td&gt;         &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;
Now, Sarah has two Phone numbers, or a single attribute with multiple values. With multi-value level attribute update support, we can do things like add a new phone number to the list, delete a phone number from the list or update a phone number (in essence by doing an add of the new value and then a delete of the old one):       &lt;table border="0" cellspacing="2" cellpadding="2" width="506"&gt;&lt;tbody&gt;
&lt;tr&gt;           &lt;td valign="top" width="128"&gt;&amp;#160;&lt;/td&gt;            &lt;td valign="top" width="170" align="right"&gt;             ID:           &lt;/td&gt;            &lt;td valign="top" width="198"&gt;12345&amp;#160; &lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td valign="top" width="128" align="right"&gt;&amp;#160;&lt;/td&gt;            &lt;td valign="top" width="170" align="right"&gt;             Type Of Change:           &lt;/td&gt;            &lt;td valign="top" width="198"&gt;Add&lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td valign="top" width="128" align="right"&gt;&amp;#160;&lt;/td&gt;            &lt;td valign="top" width="170" align="right"&gt;            Phone:           &lt;/td&gt;            &lt;td valign="top" width="198"&gt;555-987-6543&lt;/td&gt;         &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
Without this support, the source system would be required to do a “replace” action and provide FIM with all of the current values at the time of import which FIM will use to override all the values that it has for that attribute.&amp;#160; So if we start with Sarah’s record as listed just above and add the phone number 555-987-6543 and remove the phone number 555-123-4567, we would have to pass:       &lt;br /&gt;
&lt;table border="0" cellspacing="2" cellpadding="2" width="506"&gt;&lt;tbody&gt;
&lt;tr&gt;           &lt;td valign="top" width="128"&gt;&amp;#160;&lt;/td&gt;            &lt;td valign="top" width="168" align="right"&gt;             ID:           &lt;/td&gt;            &lt;td valign="top" width="201"&gt;12345&amp;#160; &lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td valign="top" width="128"&gt;&amp;#160;&lt;/td&gt;            &lt;td valign="top" width="168" align="right"&gt;             Type Of Change:           &lt;/td&gt;            &lt;td valign="top" width="201"&gt;Replace&lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td valign="top" width="128"&gt;&amp;#160;&lt;/td&gt;            &lt;td valign="top" width="168" align="right"&gt;             Phone:           &lt;/td&gt;            &lt;td valign="top" width="201"&gt;555-987-6543&lt;/td&gt;         &lt;/tr&gt;
&lt;tr&gt;           &lt;td valign="top" width="128"&gt;&amp;#160;&lt;/td&gt;            &lt;td valign="top" width="168" align="right"&gt;             Phone:           &lt;/td&gt;            &lt;td valign="top" width="201"&gt;555-4567-7890&lt;/td&gt;         &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
As with attribute level updates, multi-valued level attribute update can greatly reduce the amount of work that FIM needs to accomplish.&amp;#160; To illustrate, just imagine applying this scenario to attributes like member on an AD group that can have thousands of values.       &lt;br /&gt;
&amp;#160; &lt;/li&gt;
&lt;li&gt;&lt;font size="2"&gt;Using a multi-valued attribute in a delimited or fixed-width file requires the use of a header on the import file &lt;/font&gt;      &lt;br /&gt;
&lt;br /&gt;
So for a comma delimited file this would look like:&amp;#160; &lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID, NAME, PHONE, PHONE, PHONE       &lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 12345, Sarah, 555-123-4567, 555-987-6543, 555-456-7890       &lt;br /&gt;
&lt;br /&gt;
This would import a record for Sarah with three attributes - ID, NAME and PHONE, the last of which will have three values. A fixed width file would work the same way.       &lt;br /&gt;
&amp;#160; &lt;/li&gt;
&lt;li&gt;&lt;font size="2"&gt;While the DSML specifications themselves can actually handle attribute level updates using the addRequest, delRequest and modifyRequest operations, FIM only implements the ability to import a SearchResultEntry element which must contain all of the attributes on the object&lt;/font&gt;       &lt;br /&gt;
&lt;br /&gt;
Just a side note for those that might be curious, you can actually place the addRequest, delRequest and modifyRequest nodes in the DSML file.&amp;#160; FIM will be able to parse the file and it wont cause any errors, however these elements are completely ignored and aren’t processed by FIM.&amp;#160; I also tried sending a DSML delta to FIM with just the attribute that changed and a change type of “modify”, and I suppose not surprisingly, the object in the connector space was updated so that it only had the one attribute I specified,&amp;#160; all the other attributes originally on the object were removed.  Had any of these attributes been defined as required, this update would have failed.     &lt;br /&gt;
&amp;#160; &lt;/li&gt;
&lt;li&gt;&lt;font size="2"&gt;While you can import an update to a specific value in a multi-valued attribute, if you were to export this same change to an LDIF file, it will come through as a replace operation containing all values now present on the attribute&lt;/font&gt;       &lt;br /&gt;
&amp;#160; &lt;/li&gt;
&lt;li&gt;&lt;font size="2"&gt;While the SQL MA does not support updates to a specific value on a multi-valued attribute out of the box, I hear rumor that some customizations can be done to make this happen&lt;/font&gt; &lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-2609293061672422233?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/d6ga51M7iwA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/2609293061672422233/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=2609293061672422233&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/2609293061672422233?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/2609293061672422233?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/d6ga51M7iwA/file-based-management-agents-in.html" title="File Based Management Agents In MIIS/ILM/FIM" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.apollojack.com/2011/04/file-based-management-agents-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUNSX49fyp7ImA9WhZQFU8.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-1065595288955920080</id><published>2011-04-22T16:22:00.001-07:00</published><updated>2011-04-22T20:11:38.067-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-22T20:11:38.067-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MIIS" /><category scheme="http://www.blogger.com/atom/ns#" term="FIM" /><category scheme="http://www.blogger.com/atom/ns#" term="ILM" /><title>Small Bug Found in MIIS/ILM/FIM Identity Manager UI….</title><content type="html">&lt;p&gt;Okay, so it’s so small its hardly worth mentioning.&amp;#160; However, if you happen to run into the error “no-start-file-open” when running an import/export step or see the following message when trying to browse to your files while configuring the import step, you may be a victim of this issue.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_fcsn-2MxKvM/TbIPyHjta3I/AAAAAAAAAEs/4hAIt9qe6ZM/s1600-h/UIErrorMessage%5B7%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" border="0" alt="UIErrorMessage" src="http://lh3.ggpht.com/_fcsn-2MxKvM/TbIPyfO_iAI/AAAAAAAAAEw/Fn7pdCT7YEM/UIErrorMessage_thumb%5B5%5D.png?imgmax=800" Title="Unable to get the list of files in the management agent's working directory." /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The problem occurs when you have given your MA a name that ends in one or more periods (“.”).&amp;#160; While this is considered legal by the Identity Manager UI (FYI - Identity Manager will not allow periods at the beginning of the MA Name), the periods will get stripped off of the MaData folder automatically by Windows.&amp;#160; In my test case I named my MA “ma ,, test – with __special ,, characters – ..”, a bit excessive I know, but hey, I was testing.&amp;#160; However, my MaData folder actually turned out like:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_fcsn-2MxKvM/TbIPy38lR1I/AAAAAAAAAE0/aXILxBY41wg/s1600-h/AddressBar%5B4%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="AddressBar" border="0" alt="AddressBar" src="http://lh5.ggpht.com/_fcsn-2MxKvM/TbIPzBES8sI/AAAAAAAAAE4/Ro1JvZPJxbE/AddressBar_thumb%5B2%5D.png?imgmax=800" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;You can see why ILM could then have a problem finding the files specified in the run profile since its using the MA Name to determine the file path (i.e. its looking for it in D:\Program Files\Microsoft Identity Integration Server\MAData\ma ,, test – with __special ,, characters – ..\).&amp;#160; Further proof that this is the case can be found in the Event Viewer:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_fcsn-2MxKvM/TbIPzcXieZI/AAAAAAAAAE8/N59qCk4JCqk/s1600-h/EventViewer%5B3%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="The management agent failed on run profile because the file could not be opened." border="0" alt="EventViewer" src="http://lh3.ggpht.com/_fcsn-2MxKvM/TbIPzncipwI/AAAAAAAAAFA/T28T3ZQjKuE/EventViewer_thumb%5B1%5D.png?imgmax=800" /&gt;&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;The fix?&amp;#160; Simply open the MA properties in Identity Manager, remove any periods from the end of the MA name and it should begin working as expected.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-1065595288955920080?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/3Zw8tSXYE8g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/1065595288955920080/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=1065595288955920080&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/1065595288955920080?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/1065595288955920080?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/3Zw8tSXYE8g/small-bug-found-in-miisilmfim-identity.html" title="Small Bug Found in MIIS/ILM/FIM Identity Manager UI…." /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_fcsn-2MxKvM/TbIPyfO_iAI/AAAAAAAAAEw/Fn7pdCT7YEM/s72-c/UIErrorMessage_thumb%5B5%5D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.apollojack.com/2011/04/small-bug-found-in-miisilmfim-identity.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0IGQ305fyp7ImA9WhZQFU8.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-1267063311163499309</id><published>2011-04-21T20:31:00.000-07:00</published><updated>2011-04-22T20:32:02.327-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-22T20:32:02.327-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MA Configuration" /><category scheme="http://www.blogger.com/atom/ns#" term="ILM" /><title>Using Maexport To Import a Management Agent</title><content type="html">&lt;p&gt;Ever happen to see this little tidbit in the documentation for Identity Manager:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_fcsn-2MxKvM/TbJIMOIHgFI/AAAAAAAAAFE/-sU_JXr1Yjs/s1600-h/Maexport%5B2%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Maexport" border="0" alt="Maexport" src="http://lh4.ggpht.com/_fcsn-2MxKvM/TbJIMT4Iw-I/AAAAAAAAAFI/u2yx7xkqNlU/Maexport_thumb.png?imgmax=800" width="443" height="73" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;You can find it under the heading Import a Management Agent from a File, and well, don’t believe it for a second!&amp;#160; Its currently not possible to import a Management Agent into Identity Manager using a command line tool.&amp;#160; For now, you will have to continue to use the UI.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-1267063311163499309?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/VvykO0TNzzk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/1267063311163499309/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=1267063311163499309&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/1267063311163499309?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/1267063311163499309?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/VvykO0TNzzk/using-maexport-to-import-management.html" title="Using Maexport To Import a Management Agent" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_fcsn-2MxKvM/TbJIMT4Iw-I/AAAAAAAAAFI/u2yx7xkqNlU/s72-c/Maexport_thumb.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.apollojack.com/2011/04/using-maexport-to-import-management.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ANRng-cCp7ImA9WhZQFUw.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-8644621646839858625</id><published>2010-04-11T12:25:00.001-07:00</published><updated>2011-04-22T16:43:17.658-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-22T16:43:17.658-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="XPath" /><category scheme="http://www.blogger.com/atom/ns#" term="FIM" /><title>XPath in FIM Sets</title><content type="html">&lt;span xmlns="xmlns"&gt;   &lt;p&gt;Recently, while working with &lt;a href="http://www.identitychaos.com/"&gt;Brad&lt;/a&gt; on a FIM implementation, he told me about some issues he was having with the restrictions placed on the XPath used when building a new Set. Specifically, he wanted to be able to find people that were missing a specific attribute. This was a little tricky, but I finally came up with a solution for strings and another one for dates:       &lt;br /&gt;&lt;/p&gt;    &lt;blockquote style="border-bottom: #7ba0cd 1px solid; border-left: #7ba0cd 1px solid; padding-bottom: 10px; padding-left: 5px; padding-right: 5px; background: #d3dfee; border-top: #7ba0cd 1px solid; border-right: #7ba0cd 1px solid; padding-top: 10px"&gt;/Person[not(starts-with(&amp;lt;AttributeNameOfTypeString&amp;gt;, ''))]     &lt;br /&gt;&lt;/blockquote&gt;    &lt;blockquote style="border-bottom: #7ba0cd 1px solid; border-left: #7ba0cd 1px solid; padding-bottom: 10px; padding-left: 5px; padding-right: 5px; background: #d3dfee; border-top: #7ba0cd 1px solid; border-right: #7ba0cd 1px solid; padding-top: 10px"&gt;/Person[not(&amp;lt;AttributeNameOfTypeDateTime&amp;gt; &amp;amp;gt; '1900-01-01T00:00:00Z')]     &lt;br /&gt;&lt;/blockquote&gt;    &lt;p&gt;So, if you wanted to find everyone who was missing an AD Distinguished Name (ADDN) you would use the following filter to define the Set:     &lt;br /&gt;&lt;/p&gt;    &lt;blockquote style="border-bottom: #7ba0cd 1px solid; border-left: #7ba0cd 1px solid; padding-bottom: 10px; padding-left: 5px; padding-right: 5px; background: #d3dfee; border-top: #7ba0cd 1px solid; border-right: #7ba0cd 1px solid; padding-top: 10px"&gt;/Person[not(starts-with(ADDN, ''))]     &lt;br /&gt;&lt;/blockquote&gt; And if you wanted all of the Person objects missing a Termination Date (EmployeeEndDate):    &lt;br /&gt;    &lt;blockquote style="border-bottom: #7ba0cd 1px solid; border-left: #7ba0cd 1px solid; padding-bottom: 10px; padding-left: 5px; padding-right: 5px; background: #d3dfee; border-top: #7ba0cd 1px solid; border-right: #7ba0cd 1px solid; padding-top: 10px"&gt;/Person[not(EmployeeEndDate &amp;amp;gt; '1900-01-01T00:00:00Z')]     &lt;br /&gt;&lt;/blockquote&gt;    &lt;p&gt;These examples are specific for the Person resource object, but this same logic could be used for any resource type in the FIM Portal.&lt;/p&gt;    &lt;p&gt;UPDATE:&amp;#160; In certain instances, the above XPath will actually return more items than you would expect.&amp;#160; Check out David’s blog post to &lt;a href="http://blog.ilmbestpractices.com/2010/06/fim-sets-xpath-finding-nulls-with.html" target="_blank"&gt;find out why and what really works&lt;/a&gt;.      &lt;br /&gt;&lt;/p&gt; &lt;/span&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-8644621646839858625?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/QDdWpCshicA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/8644621646839858625/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=8644621646839858625&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/8644621646839858625?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/8644621646839858625?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/QDdWpCshicA/xpath-in-fim-sets.html" title="XPath in FIM Sets" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.apollojack.com/2010/04/xpath-in-fim-sets.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUENQXw-eCp7ImA9WxNbE0Q.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-5450742695774887742</id><published>2009-11-16T09:21:00.000-08:00</published><updated>2009-11-16T09:48:10.250-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-16T09:48:10.250-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MA Rules Extensions" /><category scheme="http://www.blogger.com/atom/ns#" term="ILM" /><title>The Missing ILM Extension</title><content type="html">While recently browsing the Microsoft.Metadirectory services namespace for ILM I discovered a new extension that I had not seen before. In addition to the 6 that I was familiar with:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;IMAExtensibleCallExport&lt;/li&gt;&lt;li&gt;IMAExtensibleFileExport&lt;/li&gt;&lt;li&gt;IMAExtensibleFileImport&lt;/li&gt;&lt;li&gt;IMAPasswordManagement&lt;/li&gt;&lt;li&gt;IMASynchronization&lt;/li&gt;&lt;li&gt;IMVSynchronization&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;There was a 7th that I had never hear of, the &lt;strong&gt;IMACalloutExtension&lt;/strong&gt;. Curious, I began to investigate. The Extension implements the following methods:&lt;/p&gt;&lt;blockquote style="background: #d3dfee; padding: 10px 5px; border: 1px solid #7ba0cd"&gt;public void BeginExportToCd(string connectTo, string user, string domain, string password)&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void EndExportToCd()&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void BeforeExportEntryToCd(string deltaEntryXml, string[] changedAttributes)&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void AfterExportEntryToCd(byte[] origAnchor, string origDN, string origDeltaEntryXml, byte[] newAnchor, string newDN, string failedDeltaEntryXml, string errorMessage)&lt;br /&gt;{&lt;br /&gt;}&lt;/blockquote&gt;&lt;p&gt;The only documentation that I could find was within the interface definition itself. It appears that this extension was to be implemented using a new Management Agent of type "Callout" (or something similar) and gives the developer the ability to take action both before and after each entry export action, which could be extremely helpful. I haven't been able to find a roadmap for this feature, but it appears to be something we can look forward to in the future!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-5450742695774887742?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/-GzwLmnjT5c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/5450742695774887742/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=5450742695774887742&amp;isPopup=true" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/5450742695774887742?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/5450742695774887742?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/-GzwLmnjT5c/missing-ilm-extension.html" title="The Missing ILM Extension" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.apollojack.com/2009/11/missing-ilm-extension.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck4HQ34-eip7ImA9WhZUFUo.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-1097974690039569434</id><published>2009-07-30T12:08:00.000-07:00</published><updated>2011-06-08T15:08:52.052-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-08T15:08:52.052-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="signedXML" /><category scheme="http://www.blogger.com/atom/ns#" term="Authentication" /><category scheme="http://www.blogger.com/atom/ns#" term="SAML" /><category scheme="http://www.blogger.com/atom/ns#" term="XML" /><category scheme="http://www.blogger.com/atom/ns#" term="Google" /><category scheme="http://www.blogger.com/atom/ns#" term="SSO" /><category scheme="http://www.blogger.com/atom/ns#" term="Certificates" /><title>.NET Google SSO Part 2 of 2</title><content type="html">&lt;span xmlns=''&gt;&lt;p&gt;This is the second in a series of articles discussing the implementation of an SSO application for Google Apps. The first &lt;a href='http://www.apollojack.com/2009/03/net-google-sso-part-1-of-2.html'&gt;.NET Google SSO Part 1 of 2&lt;/a&gt; began the discussion by laying out the steps needed to handle the initial Authentication Request made by Google. This final piece will complete the package by illustrating the generation of the Authentication Response. &lt;br /&gt;
&lt;/p&gt;&lt;p style='text-align: center'&gt;&lt;a href='http://3.bp.blogspot.com/_fcsn-2MxKvM/Sc3BWi1RBDI/AAAAAAAAACM/gNfBJyWDk1w/s1600-h/SSOProcess.jpg'&gt;&lt;img border='0' alt='' src='http://3.bp.blogspot.com/_fcsn-2MxKvM/Sc3BWi1RBDI/AAAAAAAAACM/gNfBJyWDk1w/s400/SSOProcess.jpg'/&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Google will expect the Authentication Response to come back as a form posted to the AssertionConsumerServiceURL provided by Google in the inital request. The form needs to have at least two elements on it, a &amp;lt;textarea&amp;gt; named SAMLResponse and an &amp;lt;input&amp;gt; named RelayState. The RelayState element is the url to redirect the user to at Google once the response has been sent. This is usually the same as the RelayState that Google provided to you via the RelayState url parameter. &lt;br /&gt;
&lt;br /&gt;
Building the SAMLResponse is a little bit more involved. The SAMLResponse will contain the xml body of the AuthnResponse, which has the following format:&lt;br /&gt;
&lt;/p&gt;&lt;div&gt;&lt;table border='0' style='border-collapse:collapse; background: #d3dfee' width='100%'&gt;&lt;colgroup&gt;&lt;col style='width:634px'/&gt;&lt;/colgroup&gt;&lt;tbody valign='top'&gt;
&lt;tr&gt;&lt;td style='padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  solid #7ba0cd 1.0pt; border-left:  solid #7ba0cd 1.0pt; border-bottom:  solid #7ba0cd 1.0pt; border-right:  solid #7ba0cd 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt; &lt;br /&gt;
&amp;lt;samlp:Response ID="RESPONSE_ID" IssueInstant="&lt;span style='color:red'&gt;ISSUE_INSTANT&lt;/span&gt;" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"&lt;br /&gt;
        xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"&amp;gt;&lt;br /&gt;
    &amp;lt;Signature xmlns="http://www.w3.org/2000/09/xmldsig#"&amp;gt;&lt;br /&gt;
        &amp;lt;SignedInfo&amp;gt;&lt;br /&gt;
            &amp;lt;CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /&amp;gt;&lt;br /&gt;
            &amp;lt;SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /&amp;gt;&lt;br /&gt;
            &amp;lt;Reference URI=""&amp;gt;&lt;br /&gt;
                &amp;lt;Transforms&amp;gt;&lt;br /&gt;
                    &amp;lt;Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /&amp;gt;&lt;br /&gt;
                &amp;lt;/Transforms&amp;gt;&lt;br /&gt;
                &amp;lt;DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /&amp;gt;&lt;br /&gt;
                &amp;lt;DigestValue&amp;gt;&lt;span style='color:red'&gt;DIGEST_VALUE&lt;/span&gt;&amp;lt;/DigestValue&amp;gt;&lt;br /&gt;
            &amp;lt;/Reference&amp;gt;&lt;br /&gt;
        &amp;lt;/SignedInfo&amp;gt;&lt;br /&gt;
        &amp;lt;SignatureValue&amp;gt;&lt;span style='color:red'&gt;SIGNATURE_VALUE&lt;/span&gt;&amp;lt;/SignatureValue&amp;gt;&lt;br /&gt;
        &amp;lt;KeyInfo&amp;gt;&lt;br /&gt;
            &amp;lt;KeyValue&amp;gt;&lt;br /&gt;
                &amp;lt;RSAKeyValue&amp;gt;&lt;br /&gt;
                    &amp;lt;Modulus&amp;gt;&lt;span style='color:red'&gt;RSA_KEY_MODULUS&lt;/span&gt;&amp;lt;/Modulus&amp;gt;&lt;br /&gt;
                    &amp;lt;Exponent&amp;gt;&lt;span style='color:red'&gt;RSA_KEY_EXPONENT&lt;/span&gt;&amp;lt;/Exponent&amp;gt;&lt;br /&gt;
                &amp;lt;/RSAKeyValue&amp;gt;&lt;br /&gt;
            &amp;lt;/KeyValue&amp;gt;&lt;br /&gt;
        &amp;lt;/KeyInfo&amp;gt;&lt;br /&gt;
    &amp;lt;/Signature&amp;gt;&lt;br /&gt;
    &amp;lt;samlp:Status&amp;gt;&lt;br /&gt;
        &amp;lt;samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /&amp;gt;&lt;br /&gt;
    &amp;lt;/samlp:Status&amp;gt;&lt;br /&gt;
    &amp;lt;Assertion ID="&lt;span style='color:red'&gt;ASSERTION_ID&lt;/span&gt;" IssueInstant="&lt;span style='color:red'&gt;ISSUE_INSTANT&lt;/span&gt;" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"&amp;gt;&lt;br /&gt;
        &amp;lt;Issuer&amp;gt;https://www.opensaml.org/IDP&amp;lt;/Issuer&amp;gt;&lt;br /&gt;
        &amp;lt;Subject&amp;gt;&lt;br /&gt;
            &amp;lt;NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress"&amp;gt;&lt;br /&gt;
                &lt;span style='color:red'&gt;USERNAME_STRING&lt;br /&gt;
&lt;/span&gt;            &amp;lt;/NameID&amp;gt;&lt;br /&gt;
            &amp;lt;SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"&amp;gt;&lt;br /&gt;
                &amp;lt;SubjectConfirmationData Recipient="&lt;span style='color:red'&gt;ACS_URL&lt;/span&gt;" /&amp;gt;&lt;br /&gt;
            &amp;lt;/SubjectConfirmation&amp;gt;&lt;br /&gt;
        &amp;lt;/Subject&amp;gt;&lt;br /&gt;
        &amp;lt;Conditions NotBefore="&lt;span style='color:red'&gt;NOT_BEFORE&lt;/span&gt;" NotOnOrAfter="&lt;span style='color:red'&gt;NOT_ON_OR_AFTER&lt;/span&gt;"&amp;gt;&lt;br /&gt;
        &amp;lt;/Conditions&amp;gt;&lt;br /&gt;
        &amp;lt;AuthnStatement AuthnInstant="&lt;span style='color:red'&gt;AUTHN_INSTANT&lt;/span&gt;"&amp;gt;&lt;br /&gt;
            &amp;lt;AuthnContext&amp;gt;&lt;br /&gt;
                &amp;lt;AuthnContextClassRef&amp;gt;&lt;br /&gt;
                    urn:oasis:names:tc:SAML:2.0:ac:classes:Password&lt;br /&gt;
                &amp;lt;/AuthnContextClassRef&amp;gt;&lt;br /&gt;
            &amp;lt;/AuthnContext&amp;gt;&lt;br /&gt;
        &amp;lt;/AuthnStatement&amp;gt;&lt;br /&gt;
    &amp;lt;/Assertion&amp;gt;&lt;br /&gt;
&amp;lt;/samlp:Response&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Where the items in red will need to be replaced with actual values before sending the response to Google. Here are some specs for those items:&lt;br /&gt;
&lt;/p&gt;&lt;div&gt;&lt;table border='0' style='border-collapse:collapse' width='100%'&gt;&lt;colgroup&gt;&lt;col style='width:62px'/&gt;&lt;col style='width:250px'/&gt;&lt;col style='width:519px'/&gt;&lt;/colgroup&gt;&lt;tbody valign='top'&gt;
&lt;tr style='background: #4f81bd'&gt;&lt;td style='padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  solid white 1.0pt; border-left:  solid white 1.0pt; border-bottom:  solid white 3.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white; font-family:Courier New; font-size:12pt' &gt;Attribute&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  solid white 1.0pt; border-left:  none; border-bottom:  solid white 3.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white; font-family:Courier New; font-size:12pt'&gt;Description&lt;strong&gt; &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  solid white 1.0pt; border-left:  none; border-bottom:  solid white 3.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white; font-family:Courier New; font-size:12pt'&gt;Examples&lt;strong&gt; &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style='background: #4f81bd; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  solid white 1.0pt; border-bottom:  solid white 0.75pt; border-right:  solid white 3.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white; font-family:Tahoma; font-size:10pt'&gt;ASSERTION_ID&lt;/span&gt; &lt;/p&gt;&lt;/td&gt;&lt;td style='background: #a7bfde; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 1.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;A 160-bit string made up of randomly generated lower case alpha characters from a through p&lt;/span&gt; &lt;/p&gt;&lt;/td&gt;&lt;td style='background: #a7bfde; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 1.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:black; font-family:Verdana; font-size:10pt'&gt;dfpccklacbmnmioodokleambcplpmfghahihdmna&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style='background: #4f81bd; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  solid white 1.0pt; border-bottom:  solid white 1.0pt; border-right:  solid white 3.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white; font-family:Tahoma; font-size:10pt'&gt;ISSUE_INSTANT&lt;/span&gt; &lt;/p&gt;&lt;/td&gt;&lt;td style='background: #d3dfee; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 0.75pt; border-right:  solid white 0.75pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;Should be the current date and time in the format: &lt;br /&gt;
yyyy-mm-ddThh:mm:ssZ&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #d3dfee; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 0.75pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;2000-01-01T23:01:01Z&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Tahoma; font-size:10pt'&gt;2008-10-02T05:55:23Z&lt;/span&gt; &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style='background: #4f81bd; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  solid white 1.0pt; border-bottom:  solid white 0.75pt; border-right:  solid white 3.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white; font-family:Tahoma; font-size:10pt'&gt;AUTHN_INSTANT&lt;/span&gt; &lt;/p&gt;&lt;/td&gt;&lt;td style='background: #a7bfde; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 1.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;Should be the current date and time in the format: &lt;br /&gt;
yyyy-mm-ddThh:mm:ssZ&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #a7bfde; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 1.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;2000-01-01T23:01:01Z&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Tahoma; font-size:10pt'&gt;2008-10-02T05:55:23Z&lt;/span&gt; &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style='background: #4f81bd; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  solid white 1.0pt; border-bottom:  solid white 1.0pt; border-right:  solid white 3.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white; font-family:Tahoma; font-size:10pt'&gt;NOT_BEFORE&lt;/span&gt; &lt;/p&gt;&lt;/td&gt;&lt;td style='background: #d3dfee; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 0.75pt; border-right:  solid white 0.75pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;This defines the beginning timeframe for which the authentication is valid. Should be the current date and time in the format: &lt;br /&gt;
yyyy-mm-ddThh:mm:ssZ&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #d3dfee; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 0.75pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;2000-01-01T23:01:01Z&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Tahoma; font-size:10pt'&gt;2008-10-02T05:55:23Z&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style='background: #4f81bd; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  solid white 1.0pt; border-bottom:  solid white 0.75pt; border-right:  solid white 3.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white; font-family:Tahoma; font-size:10pt'&gt;NOT_ON_OR_AFTER&lt;/span&gt; &lt;/p&gt;&lt;/td&gt;&lt;td style='background: #a7bfde; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 1.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;This defines the ending timeframe for which the authentication is valid. Should be the current date and time in the format: &lt;br /&gt;
yyyy-mm-ddThh:mm:ssZ&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #a7bfde; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 1.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;2000-01-01T23:01:01Z&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Tahoma; font-size:10pt'&gt;2008-10-02T05:55:23Z&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style='background: #4f81bd; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  solid white 1.0pt; border-bottom:  solid white 1.0pt; border-right:  solid white 3.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white; font-family:Tahoma; font-size:10pt'&gt;ACS_URL&lt;/span&gt; &lt;/p&gt;&lt;/td&gt;&lt;td style='background: #d3dfee; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 0.75pt; border-right:  solid white 0.75pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;The URL to send the authentication result&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #d3dfee; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 0.75pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;https://www.google.com/a/yourCompany.com/acs&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style='background: #4f81bd; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  solid white 1.0pt; border-bottom:  solid white 0.75pt; border-right:  solid white 3.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white; font-family:Tahoma; font-size:10pt'&gt;USERNAME_STRING&lt;/span&gt; &lt;/p&gt;&lt;/td&gt;&lt;td style='background: #a7bfde; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 1.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;The username of the person validated&lt;/span&gt; &lt;/p&gt;&lt;/td&gt;&lt;td style='background: #a7bfde; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 1.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;jsmith&lt;br /&gt;
&lt;/span&gt;jon.smith &lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style='background: #4f81bd; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  solid white 1.0pt; border-bottom:  solid white 1.0pt; border-right:  solid white 3.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white; font-family:Tahoma; font-size:10pt'&gt;DIGEST_VALUE&lt;/span&gt; &lt;/p&gt;&lt;/td&gt;&lt;td style='background: #d3dfee; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 0.75pt; border-right:  solid white 0.75pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;The value of the digest of the Reference URI calculated using the algorithm listed in the DigestMethod&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #d3dfee; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 0.75pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;Qo9gKjwBgNtt6P07aIZmIPXP+uQ=&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style='background: #4f81bd; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  solid white 1.0pt; border-bottom:  solid white 0.75pt; border-right:  solid white 3.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white; font-family:Tahoma; font-size:10pt'&gt;SIGNATURE_VALUE&lt;/span&gt; &lt;/p&gt;&lt;/td&gt;&lt;td style='background: #a7bfde; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 1.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;The value of the digest of the SignedInfo Element calculated using the algorithm listed in the SignatureMethod&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #a7bfde; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 1.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;55khyrdDp0SgPmlu5dH49CAfASW2psDLhgjaB+Yl06pfxLJWnIctb7pX0K3k/vhNU8sUMY6Ps582CS6+YUPJps45U0i&lt;br /&gt;
VDK/+PPZvFREOwDR54XSzXAPd7GZyk+jBdQZv6D/g5IgccIGiw3Zi9Qpfe64iewSFoRukvVUD0yGOfszA=&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style='background: #4f81bd; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  solid white 1.0pt; border-bottom:  solid white 1.0pt; border-right:  solid white 3.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white; font-family:Tahoma; font-size:10pt'&gt;RSA_KEY_MODULUS&lt;/span&gt; &lt;/p&gt;&lt;/td&gt;&lt;td style='background: #d3dfee; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 0.75pt; border-right:  solid white 0.75pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;For use in the RSA encryption algorithm&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #d3dfee; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 0.75pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;K88ntfSyp1JU9Nu1KJwk+KKOuunT9G1RLwJXm6WrDb2klVGXLNKcP72lu5AlyGgYoZXO2bY2d610LE7kGol3Hu&lt;br /&gt;
PKfOMLoKqO/m1etjBBhQnuc2aVL1vJjQiLV/KsCsgwocNIoGOF01ndlgJiazFUFf6IwFltNg/A1pz9I05kkj0=&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style='background: #4f81bd; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  solid white 1.0pt; border-bottom:  solid white 1.0pt; border-right:  solid white 3.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white; font-family:Tahoma; font-size:10pt'&gt;RSA_KEY_EXPONENT&lt;/span&gt; &lt;/p&gt;&lt;/td&gt;&lt;td style='background: #a7bfde; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 1.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;For use in the RSA encryption algorithm&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #a7bfde; padding-top: 1px; padding-left: 5px; padding-bottom: 1px; padding-right: 5px; border-top:  none; border-left:  none; border-bottom:  solid white 1.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Tahoma; font-size:10pt'&gt;AQAB&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Here are the basic steps we need to take to create the AuthnResponse:&lt;br /&gt;
&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Authenticate the user&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Generate an xmlDocument object using the AuthnResponse Template&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Fill in the AuthnResponse parameters &lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Create a new signedXml object based on the xmlDocument &lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Submit an html form with the InnerXml of the signedXml object and the RelayState&lt;br /&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;If we continue with the project created using the first blog post, we currently have one item on our form, a label called lblError. You will need to add two text boxes, txtUser and txtPwd to allow the user to enter their credentials and a button, btnSubmit. Format the form to your liking, and then add some code to authenticate the user, this can be done against a directory, a database, etc. This example will authenticate a user against ADAM.&lt;br /&gt;
&lt;/p&gt;&lt;div&gt;&lt;table border='0' style='border-collapse:collapse; background: #d3dfee' width='100%'&gt;&lt;colgroup&gt;&lt;col style='width:632px'/&gt;&lt;/colgroup&gt;&lt;tbody valign='top'&gt;
&lt;tr&gt;&lt;td style='padding-top: 1px; padding-left: 4px; padding-bottom: 1px; padding-right: 4px; border-top:  solid #7ba0cd 1.0pt; border-left:  solid #7ba0cd 1.0pt; border-bottom:  solid #7ba0cd 1.0pt; border-right:  solid #7ba0cd 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:green'&gt;// Class level vars&lt;/span&gt;&lt;span style='color:#333333'&gt;&lt;br /&gt;
&lt;/span&gt;&lt;span style='color:blue'&gt;string &lt;/span&gt;googleUserName &lt;span style='color:#333333'&gt;= "";&lt;/span&gt;&lt;span style='color:gray'&gt;&lt;br /&gt;
&lt;br /&gt;
///&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:gray'&gt;/// &lt;/span&gt;&lt;span style='color:green'&gt;Authenticate user and return the result&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='color:gray; font-family:Courier New; font-size:10pt'&gt;///&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;protected bool&lt;/span&gt; AuthenticateUser()&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;{&lt;br /&gt;
    &lt;span style='color:green'&gt;// User parameters from the form&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;bool &lt;/span&gt;authenticated =&lt;span style='color:blue'&gt; false;&lt;/span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:green'&gt;// User parameters from the form&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;string&lt;/span&gt; user = Request.Params[&lt;span style='color:maroon'&gt;"txtUser"&lt;/span&gt;];&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;string&lt;/span&gt; password = Request.Params[&lt;span style='color:maroon'&gt;"txtPwd"&lt;/span&gt;];&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;br /&gt;
    &lt;span style='color:green'&gt;// Variables&lt;/span&gt;&lt;br /&gt;
    SearchResult srPerson = &lt;span style='color:blue'&gt;null&lt;/span&gt;;&lt;br /&gt;
    DirectorySearcher dSearch = &lt;span style='color:blue'&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    DirectoryEntry de = &lt;span style='color:blue'&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    DirectoryEntry deAdmin = &lt;span style='color:blue'&gt;null&lt;/span&gt;;&lt;br /&gt;
    &lt;span style='color:blue'&gt;string&lt;/span&gt; dn = &lt;span style='color:maroon'&gt;""&lt;/span&gt;;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:green'&gt;// Clear out our class level variable, googleUserName&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    googleUserName = &lt;span style='color:maroon'&gt;""&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;try&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    {&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        &lt;span style='color:blue'&gt;if&lt;/span&gt; (!&lt;span style='color:blue'&gt;string&lt;/span&gt;.IsNullOrEmpty(user) &amp;amp;&amp;amp; !&lt;span style='color:blue'&gt;string&lt;/span&gt;.IsNullOrEmpty(password))&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        {&lt;br /&gt;
            &lt;span style='color:green'&gt;// All required params were not entered, throw an error&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            &lt;span style='color:green'&gt;// could also use some field validators to avoid this&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            &lt;span style='color:blue'&gt;throw new &lt;/span&gt;&lt;span style='color:teal'&gt;Exception&lt;/span&gt;(&lt;span style='color:maroon'&gt;"Logon failure: unknown user name or bad password"&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        &lt;span style='color:green'&gt;// Get the users dn based on the user name used the form, so&lt;br /&gt;
&lt;/span&gt;        &lt;span style='color:green'&gt;// that we can use it later with our bind test&lt;br /&gt;
&lt;/span&gt;        dSearch = &lt;span style='color:blue'&gt;new&lt;/span&gt; DirectorySearcher();&lt;br /&gt;
        dSearch.SearchScope = SearchScope.Subtree;&lt;br /&gt;
        dSearch.PropertiesToLoad.Add(&lt;span style='color:maroon'&gt;"distinguishedName"&lt;/span&gt;);&lt;br /&gt;
        dSearch.SearchRoot = &lt;span style='color:blue'&gt;new&lt;/span&gt; DirectoryEntry(&lt;span style='color:maroon'&gt;"LDAP://YourServer:389/C=YourRootPath"&lt;/span&gt;, &lt;span style='color:maroon'&gt;"AdamAdminUser"&lt;/span&gt;, &lt;span style='color:maroon'&gt;"AdamAdminPswd"&lt;/span&gt;, &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; AuthenticationTypes.Secure | AuthenticationTypes.ServerBind); &lt;br /&gt;
        dSearch.Filter = &lt;span style='color:maroon'&gt;"(userName="&lt;/span&gt; + user + &lt;span style='color:maroon'&gt;")"&lt;/span&gt;;&lt;br /&gt;
        srPerson = dSearch.FindOne();&lt;span style='color:green'&gt;&lt;br /&gt;
&lt;/span&gt;        dn = srPerson == &lt;span style='color:blue'&gt;null&lt;/span&gt; ? &lt;span style='color:blue'&gt;null&lt;/span&gt; : srPerson.Properties[&lt;span style='color:maroon'&gt;"distinguishedName"&lt;/span&gt;][0].ToString();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        &lt;span style='color:blue'&gt;if&lt;/span&gt; (!&lt;span style='color:blue'&gt;string&lt;/span&gt;.IsNullOrEmpty(dn))&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        {&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            &lt;span style='color:green'&gt;// Get the directory entry, using the users credentials to bind&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            de = &lt;span style='color:blue'&gt;new&lt;/span&gt; DirectoryEntry(&lt;span style='color:maroon'&gt;"LDAP://YourServer:389/C=YourRootPath"&lt;/span&gt;, dn, password, &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  AuthenticationTypes.ServerBind | AuthenticationTypes.FastBind);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                    &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            &lt;span style='color:green'&gt;// Get the native object to force authentication, an error will be throw here&lt;br /&gt;
&lt;/span&gt;            &lt;span style='color:green'&gt;// if the wrong credentials were given, this will be captured below and the user will be notified&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            &lt;span style='color:blue'&gt;object&lt;/span&gt; bind = de.NativeObject;&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            &lt;span style='color:green'&gt;// They have authenticated okay, we are now assuming that their google user name&lt;br /&gt;
&lt;/span&gt;            &lt;span style='color:green'&gt;// is different than their ADAM login name, we need to get it for use later&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            &lt;span style='color:green'&gt;// we cant use the above object to get the data because we had to issue our connection&lt;br /&gt;
&lt;/span&gt;            &lt;span style='color:green'&gt;// using the fast bind option, get a new handle on the object using&lt;br /&gt;
&lt;/span&gt;            &lt;span style='color:green'&gt;// admin credentials and the secure auth type&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            deAdmin = &lt;span style='color:blue'&gt;new&lt;/span&gt; DirectoryEntry(&lt;span style='color:maroon'&gt;"LDAP://YourServer:389/"&lt;/span&gt; + dn, &lt;span style='color:maroon'&gt;"AdamAdminUser"&lt;/span&gt;, &lt;span style='color:maroon'&gt;"AdamAdminPswd"&lt;/span&gt;, &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; AuthenticationTypes.ServerBind | AuthenticationTypes.Secure);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            deAdmin.RefreshCache(&lt;span style='color:blue'&gt;new string&lt;/span&gt;[] { &lt;span style='color:maroon'&gt;"googleUserName"&lt;/span&gt; });&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            &lt;span style='color:green'&gt;// If googleUserName is an email address, we just want what comes before the @ symbol&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            googleUserName = deAdmin.Properties.Contains(&lt;span style='color:maroon'&gt;"googleUserName"&lt;/span&gt;) ? &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; deAdmin.Properties[&lt;span style='color:maroon'&gt;"googleUserName"&lt;/span&gt;][0].ToString() : &lt;span style='color:maroon'&gt;""&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            googleUserName = googleUserName.IndexOf(&lt;span style='color:maroon'&gt;"@"&lt;/span&gt;) &amp;gt; 0 ? &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; googleUserName.Substring(0, googleUserName.IndexOf(&lt;span style='color:maroon'&gt;"@"&lt;/span&gt;)) : googleUserName;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        &lt;br /&gt;
            &lt;span style='color:green'&gt;// We didn't get what we expected throw an error&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            &lt;span style='color:blue'&gt;if&lt;/span&gt; (googleUserName == &lt;span style='color:maroon'&gt;""&lt;/span&gt;)&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            {&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                &lt;span style='color:blue'&gt;throw new &lt;/span&gt;&lt;span style='color:teal'&gt;Exception&lt;/span&gt;(&lt;span style='color:maroon'&gt;"Logon failure: unable to retrieve your Google username"&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            }&lt;br /&gt;
            &lt;span style='color:blue'&gt;else&lt;/span&gt;&lt;br /&gt;
            {&lt;br /&gt;
                authenticated = &lt;span style='color:blue'&gt;true&lt;/span&gt;;&lt;br /&gt;
            }                    &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        }&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        &lt;span style='color:blue'&gt;else&lt;br /&gt;
&lt;/span&gt;        {&lt;br /&gt;
            &lt;span style='color:green'&gt;// We cant continue without a dn&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            &lt;span style='color:blue'&gt;throw new &lt;/span&gt;&lt;span style='color:teal'&gt;Exception&lt;/span&gt;(&lt;span style='color:maroon'&gt;"Logon failure: unknown user name or bad password"&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        }&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    }&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;catch&lt;/span&gt;(&lt;span style='color:teal'&gt;Exception&lt;/span&gt; ex)&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    {&lt;br /&gt;
        &lt;span style='color:green'&gt;// Let user know there was a problem&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        lblError.Text = ex.Message;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    }&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;finally&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    {&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        &lt;span style='color:green'&gt;// Clean up&lt;br /&gt;
&lt;/span&gt;        &lt;span style='color:blue'&gt;if&lt;/span&gt; (dSearch!= &lt;span style='color:blue'&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        {&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            dSearch.Dispose();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        }&lt;br /&gt;
&lt;br /&gt;
        &lt;span style='color:blue'&gt;if&lt;/span&gt; (de != &lt;span style='color:blue'&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        {&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            de.Dispose();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        &lt;span style='color:blue'&gt;if&lt;/span&gt; (deAdmin != &lt;span style='color:blue'&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        {&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            deAdmin.Dispose();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        }&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    }&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Now that our user is authenticated and we have their Google UserName, the next step is to generate an xmlDocument object using the AuthnResponse template. The template that we need is similar to the AuthnResponse shown above, with one very important difference; we don't want the &amp;lt;Signature&amp;gt; element or its children. We will be adding this using the signedXml object later. Create an xml file named AuthnResponseTemplate in your project directory. Copy in the AuthnResponse xml below and save the document.&lt;br /&gt;
&lt;/p&gt;&lt;div&gt;&lt;table border='0' style='border-collapse:collapse; background: #d3dfee' width='100%'&gt;&lt;colgroup&gt;&lt;col style='width:638px'/&gt;&lt;/colgroup&gt;&lt;tbody valign='top'&gt;
&lt;tr&gt;&lt;td style='padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  solid #7ba0cd 1.0pt; border-left:  solid #7ba0cd 1.0pt; border-bottom:  solid #7ba0cd 1.0pt; border-right:  solid #7ba0cd 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt; &lt;br /&gt;
&amp;lt;samlp:Response ID="RESPONSE_ID" IssueInstant="&lt;span style='color:red'&gt;ISSUE_INSTANT&lt;/span&gt;" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"&lt;br /&gt;
        xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"&amp;gt;&lt;br /&gt;
    &amp;lt;samlp:Status&amp;gt;&lt;br /&gt;
        &amp;lt;samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /&amp;gt;&lt;br /&gt;
    &amp;lt;/samlp:Status&amp;gt;&lt;br /&gt;
    &amp;lt;Assertion ID="&lt;span style='color:red'&gt;ASSERTION_ID&lt;/span&gt;" IssueInstant="&lt;span style='color:red'&gt;ISSUE_INSTANT&lt;/span&gt;" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"&amp;gt;&lt;br /&gt;
        &amp;lt;Issuer&amp;gt;https://www.opensaml.org/IDP&amp;lt;/Issuer&amp;gt;&lt;br /&gt;
        &amp;lt;Subject&amp;gt;&lt;br /&gt;
            &amp;lt;NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress"&amp;gt;&lt;br /&gt;
                &lt;span style='color:red'&gt;USERNAME_STRING&lt;br /&gt;
&lt;/span&gt;            &amp;lt;/NameID&amp;gt;&lt;br /&gt;
            &amp;lt;SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"&amp;gt;&lt;br /&gt;
                &amp;lt;SubjectConfirmationData Recipient="&lt;span style='color:red'&gt;ACS_URL&lt;/span&gt;" /&amp;gt;&lt;br /&gt;
            &amp;lt;/SubjectConfirmation&amp;gt;&lt;br /&gt;
        &amp;lt;/Subject&amp;gt;&lt;br /&gt;
        &amp;lt;Conditions NotBefore="&lt;span style='color:red'&gt;NOT_BEFORE&lt;/span&gt;" NotOnOrAfter="&lt;span style='color:red'&gt;NOT_ON_OR_AFTER&lt;/span&gt;"&amp;gt;&lt;br /&gt;
        &amp;lt;/Conditions&amp;gt;&lt;br /&gt;
        &amp;lt;AuthnStatement AuthnInstant="&lt;span style='color:red'&gt;AUTHN_INSTANT&lt;/span&gt;"&amp;gt;&lt;br /&gt;
            &amp;lt;AuthnContext&amp;gt;&lt;br /&gt;
                &amp;lt;AuthnContextClassRef&amp;gt;&lt;br /&gt;
                    urn:oasis:names:tc:SAML:2.0:ac:classes:Password&lt;br /&gt;
                &amp;lt;/AuthnContextClassRef&amp;gt;&lt;br /&gt;
            &amp;lt;/AuthnContext&amp;gt;&lt;br /&gt;
        &amp;lt;/AuthnStatement&amp;gt;&lt;br /&gt;
    &amp;lt;/Assertion&amp;gt;&lt;br /&gt;
&amp;lt;/samlp:Response&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;We will now add code to consume this new file and replace the elements in red with proper values:&lt;br /&gt;
&lt;/p&gt;&lt;div&gt;&lt;table border='0' style='border-collapse:collapse; background: #d3dfee' width='100%'&gt;&lt;colgroup&gt;&lt;col style='width:638px'/&gt;&lt;/colgroup&gt;&lt;tbody valign='top'&gt;
&lt;tr&gt;&lt;td style='padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  solid #7ba0cd 1.0pt; border-left:  solid #7ba0cd 1.0pt; border-bottom:  solid #7ba0cd 1.0pt; border-right:  solid #7ba0cd 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:gray; font-family:Courier New; font-size:10pt'&gt;///&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:gray'&gt;/// &lt;/span&gt;&lt;span style='color:green'&gt;Create our xml SAML Response base on the template&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:gray'&gt;///&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style='color:blue'&gt;&lt;br /&gt;
private string&lt;/span&gt; CreateSamlResponse() &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;{&lt;br /&gt;
    &lt;span style='color:green'&gt;// Grab our response template&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;string&lt;/span&gt; filepath = Request.PhysicalApplicationPath + (&lt;span style='color:maroon'&gt;"AuthnResponseTemplate.xml"&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    XmlDocument doc = &lt;span style='color:blue'&gt;new&lt;/span&gt; XmlDocument();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    doc.PreserveWhitespace = &lt;span style='color:blue'&gt;true&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    doc.Load(filepath);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;string&lt;/span&gt; samlResponse = doc.InnerXml;&lt;/span&gt; &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;br /&gt;
    &lt;span style='color:green'&gt;// Get our IDs and make sure that they arent the same (timing)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;string&lt;/span&gt; responseID = CreateID();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;string&lt;/span&gt; assertionID = CreateID();&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;while&lt;/span&gt; (responseID == assertionID)&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    {&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        assertionID = CreateID();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    }&lt;/span&gt; &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;br /&gt;
    &lt;span style='color:green'&gt;// Fill out out our template&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    samlResponse = samlResponse.Replace(&lt;span style='color:maroon'&gt;"USERNAME_STRING"&lt;/span&gt;, googleUserName);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    samlResponse = samlResponse.Replace(&lt;span style='color:maroon'&gt;"RESPONSE_ID"&lt;/span&gt;, responseID);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    samlResponse = samlResponse.Replace(&lt;span style='color:maroon'&gt;"ISSUE_INSTANT"&lt;/span&gt;, GetDateAndTime(0, 0));&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    samlResponse = samlResponse.Replace(&lt;span style='color:maroon'&gt;"AUTHN_INSTANT"&lt;/span&gt;, GetDateAndTime(0, 1));&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    samlResponse = samlResponse.Replace(&lt;span style='color:maroon'&gt;"NOT_BEFORE"&lt;/span&gt;, GetRequestAttributes(requestXmlString, &lt;span style='color:maroon'&gt;"IssueInstant"&lt;/span&gt;));&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    samlResponse = samlResponse.Replace(&lt;span style='color:maroon'&gt;"NOT_ON_OR_AFTER"&lt;/span&gt;, GetDateAndTime(1, 0););&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    samlResponse = samlResponse.Replace(&lt;span style='color:maroon'&gt;"ASSERTION_ID"&lt;/span&gt;, assertionID);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    samlResponse = samlResponse.Replace(&lt;span style='color:maroon'&gt;"ACS_URL"&lt;/span&gt;, GetRequestAttributes(requestXmlString, &lt;span style='color:maroon'&gt;"AssertionConsumerServiceURL"&lt;/span&gt;));&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;return&lt;/span&gt; samlResponse;&lt;/span&gt; &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;}&lt;br /&gt;
&lt;br /&gt;
&lt;span style='color:gray'&gt;///&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:gray'&gt;/// &lt;/span&gt;&lt;span style='color:green'&gt;Generate a random set of alpha characters &lt;br /&gt;
&lt;/span&gt;&lt;span style='color:gray'&gt;///&lt;/span&gt;&lt;span style='color:green'&gt; appropriate for our SAML IDs&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:gray'&gt;///&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style='color:blue'&gt;&lt;br /&gt;
public static&lt;/span&gt; &lt;span style='color:blue'&gt;string&lt;/span&gt; CreateID() &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:teal'&gt;Random&lt;/span&gt; random = &lt;span style='color:blue'&gt;new &lt;/span&gt;&lt;span style='color:teal'&gt;Random&lt;/span&gt;();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;char&lt;/span&gt;[] charMapping = {&lt;span style='color:maroon'&gt;'a'&lt;/span&gt;, &lt;span style='color:maroon'&gt;'b'&lt;/span&gt;, &lt;span style='color:maroon'&gt;'c'&lt;/span&gt;, &lt;span style='color:maroon'&gt;'d'&lt;/span&gt;, &lt;span style='color:maroon'&gt;'e'&lt;/span&gt;, &lt;span style='color:maroon'&gt;'f'&lt;/span&gt;, &lt;span style='color:maroon'&gt;'g'&lt;/span&gt;, &lt;span style='color:maroon'&gt;'h'&lt;/span&gt;, &lt;span style='color:maroon'&gt;'i'&lt;/span&gt;, &lt;span style='color:maroon'&gt;'j'&lt;/span&gt;, &lt;span style='color:maroon'&gt;'k'&lt;/span&gt;, &lt;span style='color:maroon'&gt;'l'&lt;/span&gt;, &lt;span style='color:maroon'&gt;'m'&lt;/span&gt;, &lt;span style='color:maroon'&gt;'n'&lt;/span&gt;, &lt;span style='color:maroon'&gt;'o'&lt;/span&gt;, &lt;span style='color:maroon'&gt;'p'&lt;/span&gt;};&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;byte&lt;/span&gt;[] bytes = &lt;span style='color:blue'&gt;new byte&lt;/span&gt;[20]; &lt;span style='color:green'&gt;// 160 bits&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    random.NextBytes(bytes);&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;char&lt;/span&gt;[] chars = &lt;span style='color:blue'&gt;new char&lt;/span&gt;[40];&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;for&lt;/span&gt; (&lt;span style='color:blue'&gt;int&lt;/span&gt; i = 0; i &amp;lt; bytes.Length; i++) &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    {&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        &lt;span style='color:blue'&gt;int&lt;/span&gt; left = (bytes[i] &amp;gt;&amp;gt; 4) &amp;amp; 0x0f;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        &lt;span style='color:blue'&gt;int&lt;/span&gt; right = bytes[i] &amp;amp; 0x0f;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        chars[i * 2] = charMapping[left];&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        chars[i * 2 + 1] = charMapping[right];&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    }&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;string&lt;/span&gt; id = &lt;span style='color:blue'&gt;new string&lt;/span&gt;(chars);&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;return&lt;/span&gt; id;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;}&lt;br /&gt;
&lt;br /&gt;
&lt;span style='color:gray'&gt;///&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:gray'&gt;/// &lt;/span&gt;&lt;span style='color:green'&gt;Create a datetime string in the appropriate SAML format&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:gray'&gt;///&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style='color:blue'&gt;&lt;br /&gt;
public static&lt;/span&gt; &lt;span style='color:blue'&gt;string&lt;/span&gt; GetDateAndTime(&lt;span style='color:blue'&gt;int&lt;/span&gt; days, &lt;span style='color:blue'&gt;int&lt;/span&gt; minutes) &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:teal'&gt;DateTime&lt;/span&gt; dt = &lt;span style='color:teal'&gt;DateTime&lt;/span&gt;.Now;&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;if&lt;/span&gt; (days &amp;gt; 0)&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    {&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        dt = dt.AddDays(days);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    }&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;if&lt;/span&gt; (minutes &amp;gt; 0)&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    {&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        dt = dt.AddMinutes(minutes);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    }&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;return&lt;/span&gt; dt.ToString(&lt;span style='color:maroon'&gt;"yyyy-MM-dd"&lt;/span&gt;) + &lt;span style='color:maroon'&gt;'T'&lt;/span&gt; + dt.ToString(&lt;span style='color:maroon'&gt;"HH:mm:ss"&lt;/span&gt;) + &lt;span style='color:maroon'&gt;'Z'&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;}&lt;br /&gt;
&lt;br /&gt;
&lt;span style='color:gray'&gt;///&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:gray'&gt;/// &lt;/span&gt;&lt;span style='color:green'&gt;Get the specified attribute value from the SAMLRequest&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:gray'&gt;///&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style='color:blue'&gt;&lt;br /&gt;
private string&lt;/span&gt; GetRequestAttributes(&lt;span style='color:blue'&gt;string&lt;/span&gt; xmlString, &lt;span style='color:blue'&gt;string&lt;/span&gt; attribute) &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    XmlDocument doc = &lt;span style='color:blue'&gt;new&lt;/span&gt; XmlDocument();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    doc.LoadXml(xmlString);&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;if&lt;/span&gt; (doc != &lt;span style='color:blue'&gt;null&lt;/span&gt;) &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    {&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        &lt;span style='color:blue'&gt;return&lt;/span&gt; doc.DocumentElement.GetAttribute(attribute).ToString();                &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    }&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;else&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    {&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        &lt;span style='color:blue'&gt;throw new&lt;/span&gt; &lt;span style='color:teal'&gt;Exception&lt;/span&gt;(&lt;span style='color:maroon'&gt;"Error parsing AuthnRequest XML: Null document"&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    }&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Next, we will be adding the xml signature. Be sure to update the file path to the x509 cert used for signing the xml. This certificate &lt;span style='text-decoration:underline'&gt;must&lt;/span&gt; contain the private key:&lt;br /&gt;
&lt;/p&gt;&lt;div&gt;&lt;table border='0' style='border-collapse:collapse; background: #d3dfee' width='100%'&gt;&lt;colgroup&gt;&lt;col style='width:638px'/&gt;&lt;/colgroup&gt;&lt;tbody valign='top'&gt;
&lt;tr&gt;&lt;td style='padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  solid #7ba0cd 1.0pt; border-left:  solid #7ba0cd 1.0pt; border-bottom:  solid #7ba0cd 1.0pt; border-right:  solid #7ba0cd 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:gray; font-family:Courier New; font-size:10pt'&gt;///&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:gray'&gt;/// &lt;/span&gt;&lt;span style='color:green'&gt;Sign the AuthnResponse xml adding the Signature element&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:gray'&gt;///&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style='color:blue'&gt;&lt;br /&gt;
private string&lt;/span&gt; SignResponse(&lt;span style='color:blue'&gt;string&lt;/span&gt; xmlDocString)&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:green'&gt;// Get our pfx cert w/private and public keys&lt;br /&gt;
&lt;/span&gt;    &lt;span style='color:green'&gt;// we have the document on the file system, but you could also&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:green'&gt;// get it from the certificate store&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:green'&gt;// this is the same cert (with public keys only) that was provided &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:green'&gt;// to Google during the SSO set-up&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    X509Certificate2 x509 = &lt;span style='color:blue'&gt;new&lt;/span&gt; X509Certificate2();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    x509.Import("&lt;span style='color:maroon'&gt;C:\FilePathToGoogleCert\Cert.pfx&lt;/span&gt;");&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:green'&gt;// Create a new RSA signing key &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:teal'&gt;RSACryptoServiceProvider&lt;/span&gt; rsaKey = &lt;span style='color:blue'&gt;new &lt;/span&gt;&lt;span style='color:teal'&gt;RSACryptoServiceProvider&lt;/span&gt;();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    rsaKey = (&lt;span style='color:teal'&gt;RSACryptoServiceProvider&lt;/span&gt;) x509.PrivateKey;&lt;/span&gt; &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;br /&gt;
    &lt;span style='color:green'&gt;// Load our xml into a doc&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    XmlDocument doc = &lt;span style='color:blue'&gt;new&lt;/span&gt; XmlDocument();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    doc.PreserveWhitespace = &lt;span style='color:blue'&gt;true&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    doc.LoadXml(xmlDocString);&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:green'&gt;// Sign the XML document. &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:green'&gt;// Create a SignedXml object.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    SignedXml signedXml = &lt;span style='color:blue'&gt;new&lt;/span&gt; SignedXml(doc);&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:green'&gt;// Add the key to the SignedXml document.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    signedXml.SigningKey = rsaKey;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:green'&gt;// Add KeyInfo &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    KeyInfo keyInfo = &lt;span style='color:blue'&gt;new&lt;/span&gt; KeyInfo();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    keyInfo.AddClause(&lt;span style='color:blue'&gt;new&lt;/span&gt; RSAKeyValue(rsaKey));&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    signedXml.KeyInfo = keyInfo;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                        &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:green'&gt;// Create a reference to be signed.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    Reference reference = &lt;span style='color:blue'&gt;new&lt;/span&gt; Reference();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    reference.Uri = &lt;span style='color:maroon'&gt;""&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:green'&gt;// Add an enveloped transformation to the reference.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    XmlDsigEnvelopedSignatureTransform env = &lt;span style='color:blue'&gt;new&lt;/span&gt; XmlDsigEnvelopedSignatureTransform();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    reference.AddTransform(env);&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:green'&gt;// Add the reference to the SignedXml object.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    signedXml.AddReference(reference);&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:green'&gt;// Compute the signature.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    signedXml.ComputeSignature();&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:green'&gt;// Get the XML representation of the signature and save&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:green'&gt;// it to an XmlElement object.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    XmlElement xmlDigitalSignature = signedXml.GetXml();&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:green'&gt;// Append the element to the XML document.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    doc.DocumentElement.InsertBefore(doc.ImportNode(xmlDigitalSignature, &lt;span style='color:blue'&gt;true&lt;/span&gt;), doc.DocumentElement.FirstChild);&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;return&lt;/span&gt; doc.InnerXml.Trim(); &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Finally, we will bring it all together in the submit button on_click event handler and generate the html form with the SAMLResponse and RelayState and send it on to Google:&lt;br /&gt;
&lt;/p&gt;&lt;div&gt;&lt;table border='0' style='border-collapse:collapse; background: #d3dfee' width='100%'&gt;&lt;colgroup&gt;&lt;col style='width:638px'/&gt;&lt;/colgroup&gt;&lt;tbody valign='top'&gt;
&lt;tr&gt;&lt;td style='padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  solid #7ba0cd 1.0pt; border-left:  solid #7ba0cd 1.0pt; border-bottom:  solid #7ba0cd 1.0pt; border-right:  solid #7ba0cd 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:gray; font-family:Courier New; font-size:10pt'&gt;///&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:gray'&gt;/// &lt;/span&gt;&lt;span style='color:green'&gt;Handle the submit button click event, authenticate the user,&lt;br /&gt;
&lt;/span&gt;&lt;span style='color:gray'&gt;///&lt;/span&gt;&lt;span style='color:green'&gt; then create the response and submit it to Google&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:gray'&gt;///&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style='color:blue'&gt;&lt;br /&gt;
protected void&lt;/span&gt; btnSubmit_Click(&lt;span style='color:blue'&gt;object&lt;/span&gt; sender, System.&lt;span style='color:teal'&gt;EventArgs&lt;/span&gt; e)&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:green'&gt;// Authenticate user&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;if&lt;/span&gt; (AuthenticateUser())&lt;br /&gt;
    {&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        &lt;span style='color:green'&gt;// Get our SAMLResponse and sign it&lt;/span&gt;&lt;br /&gt;
        &lt;span style='color:blue'&gt;string&lt;/span&gt; samlResponse = CreateSamlResponse();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        &lt;span style='color:blue'&gt;string&lt;/span&gt; signedResponse = SignResponse(samlResponse);&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        &lt;span style='color:blue'&gt;string&lt;/span&gt; formName = "&lt;span style='color:maroon'&gt;authnResponse&lt;/span&gt;"; &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        &lt;span style='color:blue'&gt;string&lt;/span&gt; acsUrl = GetRequestAttributes(requestXmlString, &lt;span style='color:maroon'&gt;"AssertionConsumerServiceURL"&lt;/span&gt;);&lt;br /&gt;
&lt;br /&gt;
        &lt;span style='color:green'&gt;// Write the http response in such a way that the html document&lt;/span&gt;&lt;br /&gt;
        &lt;span style='color:green'&gt;// will submit a form with our data on it to the requestor&lt;/span&gt;&lt;/span&gt; &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        System.Web.HttpContext.Current.Response.Clear();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        System.Web.HttpContext.Current.Response.Write("&lt;span style='color:maroon'&gt;&amp;lt;html&amp;gt;&amp;lt;head/&amp;gt;&lt;/span&gt;");&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        System.Web.HttpContext.Current.Response.Write(&lt;span style='color:blue'&gt;string&lt;/span&gt;.Format("&lt;span style='color:maroon'&gt;&amp;lt;body onload='document.{0}.submit()'&amp;gt;&lt;/span&gt;", &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; formName));&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        System.Web.HttpContext.Current.Response.Write(&lt;span style='color:blue'&gt;string&lt;/span&gt;.Format("&lt;span style='color:maroon'&gt;&amp;lt;form name='{0}' method='post' action='{1}'&amp;gt;&lt;/span&gt;", &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; formName, acsUrl));&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        System.Web.HttpContext.Current.Response.Write(&lt;span style='color:blue'&gt;string&lt;/span&gt;.Format("&lt;span style='color:maroon'&gt;&amp;lt;textarea name=\"{0}\" style='visibility:hidden'&amp;gt;{1}&amp;lt;/textarea&amp;gt;&lt;/span&gt;", &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "&lt;span style='color:maroon'&gt;SAMLResponse&lt;/span&gt;", signedResponse));&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        System.Web.HttpContext.Current.Response.Write(&lt;span style='color:blue'&gt;string&lt;/span&gt;.Format("&lt;span style='color:maroon'&gt;&amp;lt;input name=\"{0}\" type=\"hidden\" value=\"{1}\"&amp;gt;&lt;/span&gt;", &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "&lt;span style='color:maroon'&gt;RelayState&lt;/span&gt;", Request.Params["&lt;span style='color:maroon'&gt;RelayState&lt;/span&gt;"]));&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        System.Web.HttpContext.Current.Response.Write("&lt;span style='color:maroon'&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;");&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        System.Web.HttpContext.Current.Response.Write("&lt;span style='color:maroon'&gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;/span&gt;");&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        System.Web.HttpContext.Current.Response.End();&lt;/span&gt; &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    }&lt;br /&gt;
}&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;That should do it! The user will then be allowed into their Google account.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-1097974690039569434?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/FoSnggwtmr4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/1097974690039569434/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=1097974690039569434&amp;isPopup=true" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/1097974690039569434?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/1097974690039569434?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/FoSnggwtmr4/net-google-sso-part-2-of-2.html" title=".NET Google SSO Part 2 of 2" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_fcsn-2MxKvM/Sc3BWi1RBDI/AAAAAAAAACM/gNfBJyWDk1w/s72-c/SSOProcess.jpg" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://www.apollojack.com/2009/03/net-google-sso-part-2-of-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EHSHsyfyp7ImA9WxJbGUs.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-1035734924518895419</id><published>2009-06-18T11:03:00.001-07:00</published><updated>2009-07-30T09:00:39.597-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-30T09:00:39.597-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Encryption" /><category scheme="http://www.blogger.com/atom/ns#" term="Certificates" /><title>Invalid provider type specified</title><content type="html">&lt;span xmlns=''&gt;&lt;p&gt;I recently had the need to encrypt some items in an application configuration file to secure some account passwords that were being stored there.  After consulting with &lt;a href='http://www.identitychaos.com/'&gt;Brad Turner&lt;/a&gt;, we decided to use an x509 certificate to provide the public and private keys needed for RSA encryption.  He requested one from our local certificate authority for this purpose and placed it in the machine store.  I was able to easily retrieve the cert and encrypt the data, however, I ran into some issues attempting to use it for decryption.  While trying to do an explicit conversion from the &lt;a href='http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate2.privatekey.aspx'&gt;x509Certificate2.PrivateKey&lt;/a&gt; property to an &lt;a href='http://msdn.microsoft.com/en-us/library/system.security.cryptography.rsacryptoserviceprovider.aspx'&gt;RSACryptoServiceProvider&lt;/a&gt; object:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;    &lt;span style='font-family:Courier New; font-size:10pt'&gt;RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)x509.PrivateKey;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;I received an "Invalid provider type specified" error.  I was unable to find anything related to this specific problem online, however, we were able to surmize that the error was refering to the &lt;a href='http://msdn.microsoft.com/en-us/library/aa380244(VS.85).aspx'&gt;cryptographic provider type&lt;/a&gt; used to create the certificate.  Based on some previous experience, Brad knew that the new v3 template for certificates on Windows 2008 server can cause some issues for older technologies. After creating a new certificate using an older template (v2), this error was no longer an issue.  This may be fixed with the 4.0 Framework, but be aware, if you are using 3.5 or older, you may run into this problem.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-1035734924518895419?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/cyTw_Ju7Vxo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/1035734924518895419/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=1035734924518895419&amp;isPopup=true" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/1035734924518895419?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/1035734924518895419?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/cyTw_Ju7Vxo/invalid-provider-type-specified.html" title="Invalid provider type specified" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>5</thr:total><feedburner:origLink>http://www.apollojack.com/2009/06/invalid-provider-type-specified.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcAQ38zeyp7ImA9WxJTEUU.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-4534098001096646119</id><published>2009-04-19T16:31:00.001-07:00</published><updated>2009-04-19T16:34:02.183-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-19T16:34:02.183-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="WMI" /><category scheme="http://www.blogger.com/atom/ns#" term="MIIS" /><category scheme="http://www.blogger.com/atom/ns#" term="ILM" /><title>Cannot connect to MMS WMI Service</title><content type="html">&lt;span xmlns=''&gt;&lt;p&gt;Having trouble with the WMI service for MIIS/ILM?  Try running the following commands at a command prompt:&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;regsvr32 "C:\Program Files\Microsoft Identity Integration Server\Bin\mmswmi.dll"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;mofcomp -N:root\MicrosoftIdentityIntegrationServer "C:\Program Files\Microsoft Identity Integration Server\Bin\mmswmi.mof"&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;This will re-register the libraries with the OS. Give the WMI call another try, if you continue to have problems with an Access Denied error…&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Open the Component Services Console in the Administrative Tools Folder.  &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Navigate to Console Root, Computers, My Computer, DCOM Config and then Microsoft Metadirectory Services.  &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Right click on the application entry and select Properties.  &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Go to the security tab and alter any security necessary.  &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Click OK on the Application Properties page and close out the Component Services and Computer Management Consoles.  &lt;/li&gt;&lt;/ol&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-4534098001096646119?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/uv0JN-CY8wY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/4534098001096646119/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=4534098001096646119&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/4534098001096646119?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/4534098001096646119?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/uv0JN-CY8wY/cannot-connect-to-mms-wmi-service.html" title="Cannot connect to MMS WMI Service" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.apollojack.com/2009/04/cannot-connect-to-mms-wmi-service.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcDQXsyfSp7ImA9WxVaFEo.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-8886119510916341979</id><published>2009-04-05T13:54:00.001-07:00</published><updated>2009-04-11T10:47:50.595-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-11T10:47:50.595-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MIIS" /><category scheme="http://www.blogger.com/atom/ns#" term="ILM" /><title>A Small MIIStake</title><content type="html">&lt;span xmlns=''&gt;&lt;p&gt;Okay, so to be fair the issue is actually with ILM (Version 3.3.118.0). In the previous version, MIIS 3.2.559.0, I would frequently run MAs from the Operations tab, like so... From the Operations tab, right click on the MA run of interest, and select the Run… option:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;center&gt;&lt;a href="http://4.bp.blogspot.com/_fcsn-2MxKvM/SeDVD8rKGRI/AAAAAAAAACU/0CqqMHOWAZI/s1600-h/MIIS+Run+From+Operations+-+Step+1.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 294px;" src="http://4.bp.blogspot.com/_fcsn-2MxKvM/SeDVD8rKGRI/AAAAAAAAACU/0CqqMHOWAZI/s400/MIIS+Run+From+Operations+-+Step+1.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5323489023355394322" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The resulting Run Management Agent window would then pre-populate the Management agent drop-down box and the Run profile list box with the same values as the original operation selected. Simply click OK and the selected run would be restarted (which makes it really easy to re-run a particular profile):&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;center&gt;&lt;a href="http://3.bp.blogspot.com/_fcsn-2MxKvM/SeDW6OZMaAI/AAAAAAAAAC0/kZR9-u7qOUE/s1600-h/MIIS+Run+From+Operations+-+Step+2_1.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 295px;" src="http://3.bp.blogspot.com/_fcsn-2MxKvM/SeDW6OZMaAI/AAAAAAAAAC0/kZR9-u7qOUE/s400/MIIS+Run+From+Operations+-+Step+2_1.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5323491055336450050" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Now if you attempt to do follow this same procedure in ILM…&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;center&gt;&lt;a href="http://3.bp.blogspot.com/_fcsn-2MxKvM/SeDWaMF43BI/AAAAAAAAACs/9xFlKZ6pYbU/s1600-h/MIIS+Run+From+Operations+-+Step+1_2.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 306px;" src="http://3.bp.blogspot.com/_fcsn-2MxKvM/SeDWaMF43BI/AAAAAAAAACs/9xFlKZ6pYbU/s400/MIIS+Run+From+Operations+-+Step+1_2.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5323490504962792466" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The drop down menu is not automatically set to the MA selected.  If you are used to being able to simply click the OK button from this dialog, you may inadvertently run the wrong MA.  In fact you can see where I ran an ADAM MA by accident in the middle of the test MA series of runs:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;center&gt;&lt;a href="http://3.bp.blogspot.com/_fcsn-2MxKvM/SeDVKeX7kWI/AAAAAAAAACc/1OFQ-4GRVns/s1600-h/MIIS+Run+From+Operations+-+Step+2.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 307px;" src="http://3.bp.blogspot.com/_fcsn-2MxKvM/SeDVKeX7kWI/AAAAAAAAACc/1OFQ-4GRVns/s400/MIIS+Run+From+Operations+-+Step+2.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5323489135480770914" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;So the bad news, for those of you using the current version of ILM, get use to using the drop-down menu to select the MA you want to run.  The good news… this is a planned fix in a future hotfix! Not sure which one, or when.  Anyone out there know?&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-8886119510916341979?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/LwTKAGv7X6w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/8886119510916341979/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=8886119510916341979&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/8886119510916341979?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/8886119510916341979?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/LwTKAGv7X6w/small-miistake.html" title="A Small MIIStake" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_fcsn-2MxKvM/SeDVD8rKGRI/AAAAAAAAACU/0CqqMHOWAZI/s72-c/MIIS+Run+From+Operations+-+Step+1.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.apollojack.com/2009/04/small-miistake.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMGRHg4fCp7ImA9WhZQFU4.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-6413397354591810849</id><published>2009-03-27T20:56:00.001-07:00</published><updated>2011-04-22T20:47:05.634-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-22T20:47:05.634-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="signedXML" /><category scheme="http://www.blogger.com/atom/ns#" term="Authentication" /><category scheme="http://www.blogger.com/atom/ns#" term="SAML" /><category scheme="http://www.blogger.com/atom/ns#" term="XML" /><category scheme="http://www.blogger.com/atom/ns#" term="Google" /><category scheme="http://www.blogger.com/atom/ns#" term="SSO" /><category scheme="http://www.blogger.com/atom/ns#" term="Certificates" /><title>.NET Google SSO Part 1 of 2</title><content type="html">&lt;span xmlns=''&gt;&lt;p&gt;Creating an SSO for Google can be a bit of a challenge. There are quite a few good examples for doing this in Java, but not as many for .NET. Here is my attempt to resolve that issue. This article will be broken up into two parts, the first of these is handling the authentication request from Google, the second of these will illustrate the response generation.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Let's start by getting a good overview of the design. The entire process will begin when the end-user tries to access their Google Account. If the &lt;a href='http://www.google.com/a/'&gt;Google Apps&lt;/a&gt; service has been configured to use SSO, Google will generate an Authentication Request and send it on for you to handle in your SSO. It is then up to you to perform user authentication and generate a signed Authentication Response to send back to Google. &lt;br /&gt;
&lt;/p&gt;&lt;p style='text-align: center'&gt;&lt;a href='http://3.bp.blogspot.com/_fcsn-2MxKvM/Sc3BWi1RBDI/AAAAAAAAACM/gNfBJyWDk1w/s1600-h/SSOProcess.jpg'&gt;&lt;img border='0' alt='' src='http://3.bp.blogspot.com/_fcsn-2MxKvM/Sc3BWi1RBDI/AAAAAAAAACM/gNfBJyWDk1w/s400/SSOProcess.jpg'/&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
 &lt;/p&gt;&lt;p&gt;Okay, now the details. When you receive an AuthenticationRequest from Google, it will make an http request to the URL you have specified in your Google Apps account with two additional query string parameters: SAMLRequest and RelayState. The SAMLRequest will look like a series of random letters and numbers that is in actuality a base64 encoded string containing the AuthnRequest. RelayState is the &lt;a href='http://www.rfc-editor.org/rfc/rfc1738.txt'&gt;RFC 1783&lt;/a&gt; encoded URL that the user is ultimately trying to get to, in this case probably their Google email account. So this would look something like:&lt;br /&gt;
&lt;/p&gt;&lt;p style='margin-left: 36pt'&gt;http://www.yourCompany.com/pathToPage/yourSSOPage.aspx?SAMLRequest=eJxdkN1uwjAMRl8lyn1%2f6NCEIgpim7YhsQlB2cXuQuK2KW2cxSni8Sk%2fk6bd2v7s4zOdn7qWHcGTQZvzUZxyBlahNrbK%2ba54jSZ8PpuS7FonFn2o7QZ%2beqDAhpwlcW3kvPdWoCRDwsoOSAQltouPlcjiVDiPARW2nC1fcl6rpqnLWtkDqIPU7tA4BftS1pVrGq1LpVF1pQbOvn6hsgvUkqiHpaUgbRhKaTqJRmmUTYrRo3jIxHj8zdn6funJ2Bv%2fP6z4L9b%2bNkTivSjW0Qa08aDCdcnRaPCfQyLnFWLVQqyw42xBBD4MSM9oqe%2fAb8EfjYLdZjX8FYITSdKikm2NFJK3a7IYVCUXb3dtsSR34iyZnQGwVYL1&amp;amp;RelayState=http%3a%2f%2fmail.google.com%2fa%2fyourCompany.com&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;Before we go much further, let's talk about the AuthnRequest. The AuthnRequest is an XML document that has the following format:&lt;br /&gt;
&lt;/p&gt;&lt;div&gt;&lt;table border='0' style='border-collapse:collapse; background: #d3dfee'&gt;&lt;colgroup&gt;&lt;col style='width:1056px'/&gt;&lt;/colgroup&gt;&lt;tbody valign='top'&gt;
&lt;tr&gt;&lt;td style='padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  solid #7ba0cd 1.0pt; border-left:  solid #7ba0cd 1.0pt; border-bottom:  solid #7ba0cd 1.0pt; border-right:  solid #7ba0cd 1.0pt' vAlign='middle'&gt;&lt;p&gt;&amp;lt;?xml version="1.0" encoding="UTF-8" ?&amp;gt;&lt;br /&gt;
&amp;lt;samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;strong&gt;    &lt;/strong&gt;&lt;/span&gt;ID="&lt;span style='color:#c00000'&gt;AUTHN_ID&lt;/span&gt;" &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;strong&gt;    &lt;/strong&gt;&lt;/span&gt;Version="2.0" &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;strong&gt;    &lt;/strong&gt;&lt;/span&gt;IssueInstant="&lt;span style='color:#c00000'&gt;ISSUE_INSTANT&lt;/span&gt;"&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;strong&gt;    &lt;/strong&gt;&lt;/span&gt;ProtocolBinding="urn:oasis:names.tc:SAML:2.0:bindings:HTTP-Redirect" &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;strong&gt;    &lt;/strong&gt;&lt;/span&gt;ProviderName="&lt;span style='color:#c00000'&gt;PROVIDER_NAME&lt;/span&gt;" &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;strong&gt;    &lt;/strong&gt;&lt;/span&gt;AssertionConsumerServiceURL="&lt;span style='color:#c00000'&gt;ACS_URL&lt;/span&gt;" /&amp;gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Where the items in red will be replace with actual values by Google at the time of generation. Here are some specs for those items:&lt;br /&gt;
&lt;/p&gt;&lt;div&gt;&lt;table border='0' style='border-collapse:collapse'&gt;&lt;colgroup&gt;&lt;col style='width:118px'/&gt;&lt;col style='width:557px'/&gt;&lt;col style='width:366px'/&gt;&lt;/colgroup&gt;&lt;tbody valign='top'&gt;
&lt;tr style='background: #4f81bd'&gt;&lt;td style='padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  solid white 1.0pt; border-left:  solid white 1.0pt; border-bottom:  solid white 3.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white; font-family:Courier New; font-size:12pt'&gt;&lt;strong&gt;Attribute&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  solid white 1.0pt; border-left:  none; border-bottom:  solid white 3.0pt; border-right:  solid white 1.0pt' vAlign='middle' colspan='2'&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:12pt'&gt;&lt;span style='color:white'&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  solid white 1.0pt; border-left:  none; border-bottom:  solid white 3.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:12pt'&gt;&lt;span style='color:white'&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style='background: #4f81bd; padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid white 1.0pt; border-bottom:  solid white 0.75pt; border-right:  solid white 3.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white; font-family:Courier New; font-size:10pt'&gt;AUTHN_ID&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #a7bfde; padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid white 1.0pt; border-right:  solid white 1.0pt' vAlign='middle' colspan='2'&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;A 160-bit string made up of randomly generated lower case alpha characters from a through p&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #a7bfde; padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid white 1.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:black; font-family:Courier New; font-size:10pt'&gt;dfpccklacbmnmioodokleambcplpmfghahihdmna&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style='background: #4f81bd; padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid white 1.0pt; border-bottom:  solid white 1.0pt; border-right:  solid white 3.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white; font-family:Courier New; font-size:10pt'&gt;ISSUE_INSTANT&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #d3dfee; padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid white 0.75pt; border-right:  solid white 0.75pt' vAlign='middle' colspan='2'&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;Should be the current date and time in the format: &lt;br /&gt;
yyyy-mm-ddThh:mm:ssZ&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #d3dfee; padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid white 0.75pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;2000-01-01T23:01:01Z&lt;br /&gt;
2008-10-02T05:55:23Z &lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style='background: #4f81bd; padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid white 1.0pt; border-bottom:  solid white 0.75pt; border-right:  solid white 3.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white; font-family:Courier New; font-size:10pt'&gt;PROVIDER_NAME&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #a7bfde; padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid white 1.0pt; border-right:  solid white 1.0pt' vAlign='middle' colspan='2'&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;This is the domain name of the calling application&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #a7bfde; padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid white 1.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;google.com &lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style='background: #4f81bd; padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid white 1.0pt; border-bottom:  solid white 1.0pt; border-right:  solid white 3.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:white; font-family:Courier New; font-size:10pt'&gt;ACS_URL&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #d3dfee; padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid white 1.0pt; border-right:  solid white 0.75pt' vAlign='middle' colspan='2'&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;The URL to send the authentication result to&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style='background: #d3dfee; padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid white 1.0pt; border-right:  solid white 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;https://www.google.com/a/yourCompany.com/acs&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Your first task will be determining the values of the two query parameters mentioned above and decoding them. In order to perform some of the decoding you will need to use a compression utility, I use a nice open source one available from ic#code at &lt;a href='http://www.icsharpcode.net/OpenSource/SharpZipLib/'&gt;http://www.icsharpcode.net/OpenSource/SharpZipLib/&lt;/a&gt;. &lt;br /&gt;
&lt;/p&gt;&lt;p&gt;So let's begin! Start a new web project and then make sure you add the following references: ICSharpCode.SharpZipLib and System.Security. Edit the default.aspx page, adding the following using statements…&lt;br /&gt;
&lt;/p&gt;&lt;div&gt;&lt;table border='0' style='border-collapse:collapse; background: #d3dfee'&gt;&lt;colgroup&gt;&lt;col style='width:1056px'/&gt;&lt;/colgroup&gt;&lt;tbody valign='top'&gt;
&lt;tr&gt;&lt;td style='padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  solid #7ba0cd 1.0pt; border-left:  solid #7ba0cd 1.0pt; border-bottom:  solid #7ba0cd 1.0pt; border-right:  solid #7ba0cd 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; System;&lt;br /&gt;
&lt;span style='color:blue'&gt;using&lt;/span&gt; System.Collections;&lt;br /&gt;
&lt;span style='color:blue'&gt;using&lt;/span&gt; System.ComponentModel;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; System.Data;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; System.Drawing;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; System.Web;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; System.Web.SessionState;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; System.Web.UI;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; System.Web.UI.WebControls;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; System.Web.UI.HtmlControls;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; System.Xml;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; System.Text;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; System.IO;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; ICSharpCode.SharpZipLib.Zip;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; ICSharpCode.SharpZipLib.Zip.Compression;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; ICSharpCode.SharpZipLib.Zip.Compression.Streams;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; System.Security;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; System.Security.Cryptography;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; System.Security.Cryptography.Xml;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; System.DirectoryServices;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; System.Security.Permissions; &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;using&lt;/span&gt; System.Security.Cryptography.X509Certificates;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Next, are the basic steps we need to take to decode the AuthnRequest:&lt;br /&gt;
&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Retrieve data from the query string&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Decode the base64 string to a byte array&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Decompress (inflate) the array&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;UTF8 Encode the array back into a string&lt;br /&gt;
&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;So here's what the code looks like to do all of that, however, you will first need to add a label to your form called lblError to communicate any issues back to the user:&lt;br /&gt;
&lt;/p&gt;&lt;div&gt;&lt;table border='0' style='border-collapse:collapse; background: #d3dfee'&gt;&lt;colgroup&gt;&lt;col style='width:1056px'/&gt;&lt;/colgroup&gt;&lt;tbody valign='top'&gt;
&lt;tr&gt;&lt;td style='padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  solid #7ba0cd 1.0pt; border-left:  solid #7ba0cd 1.0pt; border-bottom:  solid #7ba0cd 1.0pt; border-right:  solid #7ba0cd 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='color:gray; font-family:Courier New; font-size:10pt'&gt;///&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:gray'&gt;/// &lt;/span&gt;&lt;span style='color:green'&gt;Converts the SAMLRequest query string parameter back to &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:gray'&gt;/// &lt;/span&gt;&lt;span style='color:green'&gt;its native, user readable XML format&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='color:gray; font-family:Courier New; font-size:10pt'&gt;///&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;private string&lt;/span&gt; decodeAuthnRequestXML()&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;{&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;try&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    {&lt;/span&gt;&lt;br /&gt;
&lt;span style='color:green; font-family:Courier New; font-size:10pt'&gt;        // Get the SAMLRequest parameter&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;        string&lt;/span&gt; encodedRequestXmlString = Request.Params[&lt;span style='color:maroon'&gt;"SAMLRequest"&lt;/span&gt;];&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;        if&lt;/span&gt; (encodedRequestXmlString != &lt;span style='color:blue'&gt;null&lt;/span&gt; &amp;amp;&amp;amp; encodedRequestXmlString != &lt;span style='color:maroon'&gt;""&lt;/span&gt;) &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        {&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            &lt;span style='color:green'&gt;// Base64 decode it&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            &lt;span style='color:blue'&gt;byte&lt;/span&gt;[] base64DecodedByteArray = &lt;span style='color:teal'&gt;Convert&lt;/span&gt;.FromBase64String(encodedRequestXmlString);&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            &lt;span style='color:green'&gt;// Uncompress the AuthnRequest data&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            &lt;span style='color:green'&gt;// First attempt to unzip the byte array according &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:green'&gt;        &lt;/span&gt;    &lt;span style='color:green'&gt;// to DEFLATE (rfc 1951)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            &lt;span style='color:blue'&gt;try&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            {   &lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                Inflater inflater = &lt;span style='color:blue'&gt;new&lt;/span&gt; Inflater(&lt;span style='color:blue'&gt;true&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                inflater.SetInput(base64DecodedByteArray);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                       &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                &lt;span style='color:green'&gt;// since we are decompressing, we dont &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:green'&gt;        &lt;/span&gt;   &lt;span style='color:green'&gt;     // know how much space we might need&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                &lt;span style='color:green'&gt;// hopefully this number is suitably big&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                &lt;span style='color:blue'&gt;byte&lt;/span&gt;[] xmlMessageBytes = &lt;span style='color:blue'&gt;new byte&lt;/span&gt;[2048];&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                &lt;span style='color:blue'&gt;int&lt;/span&gt; resultLength = inflater.Inflate(xmlMessageBytes); &lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                &lt;span style='color:blue'&gt;if&lt;/span&gt; (!inflater.IsFinished) &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                {&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                    lblError.Text = &lt;span style='color:maroon'&gt;"Error decoding AuthnRequest: " &lt;/span&gt;+&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:maroon'&gt;      &lt;/span&gt;   &lt;span style='color:maroon'&gt;               "Decompression data overflow"&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                    &lt;span style='color:blue'&gt;return null&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                }&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;   &lt;span style='color:green'&gt;             // UTF8 encode the result and return it&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                &lt;span style='color:teal'&gt;UTF8Encoding&lt;/span&gt; utf8 = &lt;span style='color:blue'&gt;new &lt;/span&gt;&lt;span style='color:teal'&gt;UTF8Encoding&lt;/span&gt;();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                &lt;span style='color:blue'&gt;return&lt;/span&gt; utf8.GetString(xmlMessageBytes, 0, resultLength);&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            } &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            &lt;span style='color:blue'&gt;catch&lt;/span&gt; (&lt;span style='color:teal'&gt;Exception&lt;/span&gt; e) &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            {&lt;/span&gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                &lt;span style='color:green'&gt;// if DEFLATE fails, then attempt to unzip &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:green'&gt;        &lt;/span&gt;   &lt;span style='color:green'&gt;     // the byte array according to zlib (rfc 1950) &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                &lt;span style='color:teal'&gt;MemoryStream&lt;/span&gt; msIn = &lt;span style='color:blue'&gt;new &lt;/span&gt;&lt;span style='color:teal'&gt;MemoryStream&lt;/span&gt;(base64DecodedByteArray);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                &lt;span style='color:teal'&gt;MemoryStream&lt;/span&gt; msOut = &lt;span style='color:blue'&gt;new &lt;/span&gt;&lt;span style='color:teal'&gt;MemoryStream&lt;/span&gt;();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                InflaterInputStream iis = &lt;span style='color:blue'&gt;new&lt;/span&gt; InflaterInputStream(msIn);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                &lt;span style='color:blue'&gt;byte&lt;/span&gt;[] buf = &lt;span style='color:blue'&gt;new byte&lt;/span&gt;[2048];&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                &lt;span style='color:blue'&gt;int&lt;/span&gt; count = iis.Read(buf, 0, buf.Length);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                &lt;span style='color:blue'&gt;while&lt;/span&gt; (count != 0) &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                {&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                    msOut.Write(buf, 0, count);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                    count = iis.Read(buf, 0, buf.Length);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                }&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                    &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                iis.Close();&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                &lt;span style='color:blue'&gt;byte&lt;/span&gt;[] retVal = &lt;span style='color:blue'&gt;new byte&lt;/span&gt;[msOut.Length];&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                msOut.Position = 0;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                msOut.Read(retVal, 0, (&lt;span style='color:blue'&gt;int&lt;/span&gt;) msOut.Length);    &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;   &lt;span style='color:green'&gt;             // UTF8 encode the result and return it&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                &lt;span style='color:blue'&gt;return&lt;/span&gt; utf8.GetString(retVal);&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;            } &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        } &lt;br /&gt;
&lt;span style='color:blue'&gt;        else&lt;/span&gt;&lt;br /&gt;
&lt;span style='color:blue'&gt;        &lt;/span&gt;{&lt;br /&gt;
&lt;span style='color:blue'&gt;                &lt;/span&gt;lblError.Text = &lt;span style='color:maroon'&gt;"Error decoding AuthnRequest: " &lt;/span&gt;+&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:maroon'&gt;      &lt;/span&gt;   &lt;span style='color:maroon'&gt;               "Unable to read SAMLRequest"&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                &lt;span style='color:blue'&gt;return null&lt;/span&gt;;&lt;br /&gt;
&lt;span style='color:blue'&gt;        &lt;/span&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    } &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    &lt;span style='color:blue'&gt;catch&lt;/span&gt; (&lt;span style='color:teal'&gt;Exception&lt;/span&gt; e) &lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    {&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;        &lt;span style='color:blue'&gt;throw new &lt;/span&gt;&lt;span style='color:teal'&gt;Exception&lt;/span&gt;(&lt;span style='color:maroon'&gt;"Error decoding AuthnRequest: "&lt;/span&gt; +&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;                    &lt;span style='color:maroon'&gt;"Check decoding scheme - "&lt;/span&gt; + e.Message);&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;    }&lt;/span&gt;&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;This code can be called from the Page_Load method to validate the request before prompting the user for their credentials. Be sure to check the Page.IsPostBack property to only call decodeAuthnRequestXML function on the initial page load. &lt;br /&gt;
&lt;/p&gt;&lt;div&gt;&lt;table border='0' style='border-collapse:collapse; background: #d3dfee'&gt;&lt;colgroup&gt;&lt;col style='width:1056px'/&gt;&lt;/colgroup&gt;&lt;tbody valign='top'&gt;
&lt;tr&gt;&lt;td style='padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  solid #7ba0cd 1.0pt; border-left:  solid #7ba0cd 1.0pt; border-bottom:  solid #7ba0cd 1.0pt; border-right:  solid #7ba0cd 1.0pt' vAlign='middle'&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:green'&gt;// Class level vars&lt;/span&gt;&lt;br /&gt;
&lt;span style='color:blue'&gt;string&lt;/span&gt; requestXmlString = null;&lt;br /&gt;
&lt;br /&gt;
&lt;span style='color:gray'&gt;///&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='color:gray'&gt;/// &lt;/span&gt;&lt;span style='color:green'&gt;Handles the page onload event&lt;/span&gt;&lt;br /&gt;
&lt;span style='color:gray'&gt;/// &lt;/span&gt;&lt;span style='color:green'&gt;Begins Authentication Request decoding&lt;/span&gt;&lt;br /&gt;
&lt;span style='color:gray'&gt;///&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style='color:blue'&gt;private void&lt;/span&gt; Page_Load()&lt;br /&gt;
{&lt;br /&gt;
    &lt;span style='color:blue'&gt;if&lt;/span&gt; (!IsPostBack)&lt;br /&gt;
    {&lt;br /&gt;
        &lt;span style='color:green'&gt;// Validate initially to force asterisks&lt;br /&gt;
&lt;/span&gt;        &lt;span style='color:green'&gt;// to appear before the first roundtrip.&lt;/span&gt;&lt;br /&gt;
        requestXmlString = decodeAuthnRequestXML();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;The string you get back from the decodeAuthnRequestXML function should be user readable XML with the AuthnRequest format mentioned above. It should look something like: &lt;br /&gt;
&lt;/p&gt;&lt;div&gt;&lt;table border='0' style='border-collapse:collapse; background: #d3dfee'&gt;&lt;colgroup&gt;&lt;col style='width:1056px'/&gt;&lt;/colgroup&gt;&lt;tbody valign='top'&gt;
&lt;tr&gt;&lt;td style='padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  solid #7ba0cd 1.0pt; border-left:  solid #7ba0cd 1.0pt; border-bottom:  solid #7ba0cd 1.0pt; border-right:  solid #7ba0cd 1.0pt' vAlign='middle'&gt;&lt;p&gt;&amp;lt;?xml version="1.0" encoding="UTF-8" ?&amp;gt;&lt;br /&gt;
&amp;lt;samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;strong&gt;    &lt;/strong&gt;&lt;/span&gt;ID="hcjjhfhcnkeckadpkjpcebfahgpjjddfcdocmfde" &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;strong&gt;    &lt;/strong&gt;&lt;/span&gt;Version="2.0" &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;strong&gt;    &lt;/strong&gt;&lt;/span&gt;IssueInstant="2009-03-26T16:32:44Z"&lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;strong&gt;    &lt;/strong&gt;&lt;/span&gt;ProtocolBinding="urn:oasis:names.tc:SAML:2.0:bindings:HTTP-Redirect" &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;strong&gt;    &lt;/strong&gt;&lt;/span&gt;ProviderName="google.com" &lt;br /&gt;
&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;strong&gt;    &lt;/strong&gt;&lt;/span&gt;AssertionConsumerServiceURL="https://www.google.com/a/yourcompany.com/acs" /&amp;gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Once you have that, you can parse the XMLDocument and begin building your response. Look for &lt;a href='http://www.apollojack.com/2009/03/net-google-sso-part-2-of-2.html'&gt;Part 2&lt;/a&gt; of the SSO series to demonstrate the building of the AuthnResponse.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-6413397354591810849?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/gh60tpL_QWo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/6413397354591810849/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=6413397354591810849&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/6413397354591810849?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/6413397354591810849?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/gh60tpL_QWo/net-google-sso-part-1-of-2.html" title=".NET Google SSO Part 1 of 2" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_fcsn-2MxKvM/Sc3BWi1RBDI/AAAAAAAAACM/gNfBJyWDk1w/s72-c/SSOProcess.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.apollojack.com/2009/03/net-google-sso-part-1-of-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cESH06fCp7ImA9WxJWEUU.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-7741057423983216761</id><published>2009-01-25T09:21:00.000-08:00</published><updated>2009-06-16T14:50:09.314-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-16T14:50:09.314-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SharePoint WebParts" /><title>Anyone know where I can find a good Locksmith?</title><content type="html">&lt;br/&gt;I recently had the need to develop a WebPart for a client that needed to be able to "unlock" a site collection. For any of you that have tried this from within a WebPart running on the SharePoint platform, you know there are quite a few issues that can come up.&lt;br /&gt;&lt;br /&gt;There are four different types of locks that can be set, here is a quick mapping of how those locks match up with the SPSite locking properties:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;table border=0 cellpadding=7 cellspacing=2&gt;&lt;tr&gt;&lt;td&gt;Not locked / none&lt;/td&gt;&lt;td&gt;site.writeLocked = false&lt;br/&gt;site.readOnly = false&lt;br/&gt;site.readLocked = false&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Adding content prevented / noadditions&lt;/td&gt;&lt;td&gt;site.writeLocked = true&lt;br/&gt;site.readOnly = false&lt;br/&gt;site.readLocked = false&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Read-only / readonly&lt;/td&gt;&lt;td&gt;site.writeLocked = false&lt;br/&gt;site.readOnly = true&lt;br/&gt;site.readLocked = false&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;No access / noaccess&lt;/td&gt;&lt;td&gt;site.writeLocked = false&lt;br/&gt;site.readOnly = false&lt;br/&gt;site.readLocked = true&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/blockquote&gt;&lt;br /&gt;Additionally, when a site is locked using any one of the lock options, the site.LockIssue is used to describe the reason for the lock.  If the site was locked using the Central Administraion console, the Additional lock information (LockIssue) field is required when locking the site.  However, this parameter is not set when locking a site using the command line interface stsadm.&lt;br /&gt;&lt;br /&gt;Here are just a few of the error messages I ran into while trying to set the lock options outright in my WebPart:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Updates are currently disallowed on GET requests. To allow updates on a GET, set the 'AllowUnsafeUpdates' property on SPWeb. &lt;br /&gt;&lt;li&gt;The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again. &lt;br /&gt;&lt;li&gt;Access to this Web site has been blocked. &lt;br /&gt;&lt;li&gt;Attempted to perform an unauthorized operation. &lt;br /&gt;&lt;li&gt;Access denied.&lt;/ol&gt;With the exception of the first error, the remainder of the messages all center around permissions and access. With that in mind, I went about trying to build some solutions using the typical SharePoint methods to elevate the privileges of the code being executed. The first of these is the SPSecurity.RunWithElevatedPrivileges. With impersonation turned on in our web.config file, the code is running under the context of the SharePoint user. This method appears to elevate the code to run under the service account on the application pool. &lt;pre style="Padding: 15px; BACKGROUND-COLOR: #cccccc"&gt;SPSecurity.RunWithElevatedPrivileges(delegate()&lt;br /&gt;{&lt;br /&gt;   using (SPSite site = new SPSite(siteUrl))&lt;br /&gt;   {&lt;br /&gt;      site.AllowUnsafeUpdates = true;&lt;br /&gt;      site.ReadLocked = false;&lt;br /&gt;      site.ReadOnly = false;&lt;br /&gt;      site.WriteLocked = false;&lt;br /&gt;      site.LockIssue = "";&lt;br /&gt;   }&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;Next, with no more luck, I tried to initialize a instance of the site class running under the context of my administration account. &lt;br /&gt;&lt;pre style="Padding: 15px; BACKGROUND-COLOR: #cccccc"&gt;using (SPSite site = new SPSite(siteUrl, SPContext.Current.Web.AllUsers["domain\\adminUsername"].UserToken))&lt;br /&gt;{&lt;br /&gt;   site.AllowUnsafeUpdates = true;&lt;br /&gt;   site.ReadLocked = false;&lt;br /&gt;   site.ReadOnly = false;&lt;br /&gt;   site.WriteLocked = false;&lt;br /&gt;   site.LockIssue = "";&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;After a little bit more investigating, I discovered that in order to perform the unlock procedures that I needed, full blown code impersonation was needed. With a little bit of additional code, I had the access that I needed. &lt;pre style="Padding: 15px; BACKGROUND-COLOR: #cccccc"&gt;//get global admin access to perform the work&lt;br /&gt;ImpersonateValidUser("domain", "adminUsername", "password");&lt;br /&gt; &lt;br /&gt;using (SPSite site = new SPSite(siteUrl))&lt;br /&gt;{&lt;br /&gt;   site.WebApplication.FormDigestSettings.Enabled = false;&lt;br /&gt;   site.AllowUnsafeUpdates = true;&lt;br /&gt;   site.ReadLocked = false;&lt;br /&gt;   site.ReadOnly = false;&lt;br /&gt;   site.WriteLocked = false;&lt;br /&gt;   site.LockIssue = "";&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;UndoImpersonation();&lt;/pre&gt;The code to implement the ImpersonateValidUser and UndoImpersonation functions can be found here: &lt;a href="http://www.codeproject.com/KB/cs/zetaimpersonator.aspx"&gt;http://www.codeproject.com/KB/cs/zetaimpersonator.aspx&lt;/a&gt;, a wonderful bit of code from Uwe Keim.&lt;br /&gt;&lt;br /&gt;By adding the line &lt;em&gt;site.WebApplication.FormDigestSettings.Enabled = false&lt;/em&gt; to the code, we are able circumvent error #2.  All of the remaining errors should be taken care of by our code impersonation. However, be warned that if the site has either readOnly or readLocked set to true, you will still have issues accessing values of various site properties.  You will need to unlock the site to get the values that you need.  If desired, you can then set the locks back to their previous state (assuming you have saved the state somewhere). And yes, you will even run into errors simply trying to save off this state for later use. The specific type of error that gets thrown will tell you everything you need to know about which of the three locks has been set.&lt;br /&gt;&lt;br /&gt;When implementing the code, be sure that it is not executing when the page initially loads, otherwise you will run into error #1. Rather run the code during a page post back (i.e. in an event handler to manage the WebPart form submittal).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-7741057423983216761?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/2dAu_bapk_k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/7741057423983216761/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=7741057423983216761&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/7741057423983216761?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/7741057423983216761?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/2dAu_bapk_k/i-recently-had-need-to-develop-webpart.html" title="Anyone know where I can find a good Locksmith?" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.apollojack.com/2009/01/i-recently-had-need-to-develop-webpart.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04BQ30yeCp7ImA9WxVSGUs.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-7293030187007789317</id><published>2008-12-11T09:26:00.000-08:00</published><updated>2009-01-14T12:45:52.390-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-14T12:45:52.390-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SharePoint WebParts" /><title>Site Navigator Released</title><content type="html">Ensynch has just released a new SharePoint WebPart that will display a tree view of all of the sites in your SharePoint environment. Props to Joe Zamora and Jerry Camel for all of their development efforts, designing and creating this WebPart.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://1.bp.blogspot.com/_fcsn-2MxKvM/SUFYJInhPVI/AAAAAAAAABQ/9ZD0bub9wc0/s1600-h/SiteNav.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 285px; height: 214px;" src="http://1.bp.blogspot.com/_fcsn-2MxKvM/SUFYJInhPVI/AAAAAAAAABQ/9ZD0bub9wc0/s400/SiteNav.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5278597152210238802" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;There are two versions of the Site Navigator, the Lite Version and the Professional Version. The Lite Version, is available at no cost and will allow you to select a starting point for the tree and additionally will allow you to "trim the tree" based on user permissions.  The Professional version, which is available for a small fee, adds some additional functionality to set the automatic expansion depth, show site collections only, and adds an option to select which web applications to show instead of setting a URL starting point.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://3.bp.blogspot.com/_fcsn-2MxKvM/SUFZSL0P5UI/AAAAAAAAABY/HdxnKoB6dR8/s1600-h/SiteNavProps.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 226px; height: 393px;" src="http://3.bp.blogspot.com/_fcsn-2MxKvM/SUFZSL0P5UI/AAAAAAAAABY/HdxnKoB6dR8/s400/SiteNavProps.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5278598407199384898" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;If you are interested in either the Lite or Pro version, simply drop a line to &lt;b&gt;&lt;a href='mailto:SharePointSolutions@Ensynch.com'&gt;SharePointSolutions@Ensynch.com&lt;/a&gt;&lt;/b&gt; and we will get you hooked up. And in case you just want to know how we did it, here are some of the details, with a few minor changes to simplify the illustration...&lt;br /&gt;&lt;br /&gt;After you create a Class Library project, make sure you add a reference to the Microsoft.SharePoint namespace and have all of the following using commands:&lt;br /&gt;&lt;blockquote style="PADDING-RIGHT: 15px; PADDING-LEFT: 15px; PADDING-BOTTOM: 15px; PADDING-TOP: 15px; BACKGROUND-COLOR: #cccccc"&gt;using System;&lt;br /&gt;using System.Collections;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Runtime.InteropServices;&lt;br /&gt;using System.Security.Principal;&lt;br /&gt;using System.Web.UI;&lt;br /&gt;using System.Web.UI.WebControls;&lt;br /&gt;using System.Web.UI.WebControls.WebParts;&lt;br /&gt;using System.Xml.Serialization;&lt;br /&gt;using Microsoft.SharePoint;&lt;br /&gt;using Microsoft.SharePoint.WebControls;&lt;br /&gt;using Microsoft.SharePoint.WebPartPages;&lt;br /&gt;using Microsoft.SharePoint.Administration;&lt;br /&gt;&lt;/blockquote&gt;Also, you will need to add two classes to your .cs file.  One of these classes will be used to build and render the WebPart Tree and the other will be implementing the EditorPart class to build the property modification pane. There are a couple of methods that must be implemented in both classes:&lt;br /&gt;&lt;blockquote style="PADDING-RIGHT: 15px; PADDING-LEFT: 15px; PADDING-BOTTOM: 15px; PADDING-TOP: 15px; BACKGROUND-COLOR: #cccccc"&gt;public class SPSiteCollectionNav : System.Web.UI.WebControls.WebParts.WebPart, IWebEditable&lt;br /&gt;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;public SPSiteCollectionNav()&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//IWebEditable Members&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;EditorPartCollection IWebEditable.CreateEditorParts()&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;List&lt;EditorPart&gt; editors = new List&lt;EditorPart&gt;();&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return new EditorPartCollection(editors);&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;object IWebEditable.WebBrowsableObject&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;get { return this; }&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//WebPart override methods&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;protected override void CreateChildControls()&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;base.CreateChildControls();&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;this.ChildControlsCreated = true;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;protected override void Render(HtmlTextWriter writer)&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;RenderChildren(writer);&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class TreeViewEditor : EditorPart, ICallbackEventHandler&lt;br /&gt;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;public TreeViewEditor()&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//EditorPart override methods&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;protected override void CreateChildControls()&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;public override bool ApplyChanges()&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;EnsureChildControls();&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return true;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;public override void SyncChanges()&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;EnsureChildControls();&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//ICallbackEventHandler Members&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;private string _argument = string.Empty;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;public void RaiseCallbackEvent(string eventArgument)&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//store the argument in a local variable so we can use it in the "GetCallbackResult" method&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//later on if necessary.&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;_argument = eventArgument;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;public string GetCallbackResult()&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return string.Empty;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;}&lt;/blockquote&gt;We are going to discuss building the SPSiteCollectionNav class first. Now that we have implemented all of the necessary functions, we can begin customizing our code. We are going to use the CreateChildControls() method to initiate the creation our tree and add it to the WebPart Controls Collection. We are also going to add a new property that we can set with our EditorPart to dynamically change properties of our tree display. Here is enough to get you started.&lt;br /&gt;&lt;blockquote style="PADDING-RIGHT: 15px; PADDING-LEFT: 15px; PADDING-BOTTOM: 15px; PADDING-TOP: 15px; BACKGROUND-COLOR: #cccccc"&gt;private TreeView tree;&lt;br /&gt;&lt;br /&gt;public SPSiteCollectionNav()&lt;br /&gt;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;tree = new TreeView();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#006600;"&gt;//lets add a property to turn on and off a create date tag&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#006600;"&gt;//appended to the tree node text, for EditorPart demonstration&lt;/span&gt;&lt;br /&gt;private bool showCreateDate;&lt;br /&gt;&lt;br /&gt;[WebBrowsable(false), Personalizable(PersonalizationScope.Shared)]&lt;br /&gt;public bool ShowCreateDate&lt;br /&gt;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;get { return showCreateDate; }&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;set { showCreateDate = value; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;EditorPartCollection IWebEditable.CreateEditorParts()&lt;br /&gt;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;List&lt;EditorPart&gt; editors = new List&lt;EditorPart&gt;();&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//add our EditorPart to the editors collection&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;TreeViewEditor editor = new TreeViewEditor();&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;editors.Add(editor);&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;return new EditorPartCollection(editors);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected override void CreateChildControls()&lt;br /&gt;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;base.CreateChildControls();&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;Controls.Clear();&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//Elevate our privs so that we can get access to the Server Farm&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;SPSecurity.CodeToRunElevated myCodeToRun = new SPSecurity.CodeToRunElevated(PopulateTreeControl);&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;SPSecurity.RunWithElevatedPrivileges(myCodeToRun);&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//Create the tree and add it to the page&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;Controls.Add(tree);&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;this.ChildControlsCreated = true;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;private void PopulateTreeControl()&lt;br /&gt;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//clear out the tree so we can start fresh&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;tree.Nodes.Clear();&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//get the servers in the local farm&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;SPFarm farm = SPFarm.Local;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;SPWebService service = farm.Services.GetValue&lt;SPWebService&gt;("");&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//enumerate the servers and add them to the tree&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;foreach (SPWebApplication webApp in service.WebApplications)&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;TreeNode webAppNode = new TreeNode();&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;webAppNode.Text = webApp.Name;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;   &lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (showCreateDate)&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;webAppNode.Text += " Created On: " + webApp.Created.ToString();&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;   &lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;webAppNode.NavigateUrl = null;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;tree.Nodes.Add(webAppNode); &lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;              &lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//TODO: add code to enumerate the sites under &lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//the web app and add them to the tree&lt;/span&gt;   &lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;              &lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;}&lt;/blockquote&gt;Next, we will work on adding some customizable properties to our WebPart.  This is done with the EditorPart.&lt;blockquote style="PADDING-RIGHT: 15px; PADDING-LEFT: 15px; PADDING-BOTTOM: 15px; PADDING-TOP: 15px; BACKGROUND-COLOR: #cccccc"&gt;private CheckBox showCreateDateCheckBox;&lt;br /&gt;&lt;br /&gt;public TreeViewEditor()&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//instantiate our create date checkbox&lt;/span&gt; &lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;showCreateDateCheckBox = new CheckBox();&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected override void CreateChildControls()&lt;br /&gt;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//add the create date checkbox to our properties pane&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;showCreateDateCheckBox.Text = "&amp;nbsp;&amp;nbsp;Show Create Date with Site Title";&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;Controls.Add(showCreateDateCheckBox);&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;Controls.Add(new LiteralControl("&amp;lt;div style='width:100%' class='UserDottedLine'&amp;gt;&amp;lt;/div&amp;gt;"));&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;public override bool ApplyChanges()&lt;br /&gt;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;EnsureChildControls();&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;SPSiteCollectionNav part = WebPartToEdit as SPSiteCollectionNav;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (part != null)&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//save the checkbox value back to the WebPart&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;part.ShowCreateDate = showCreateDateCheckBox.Checked;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;else&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return false;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;return true;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;}&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;public override void SyncChanges()&lt;br /&gt;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;EnsureChildControls();&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;SPSiteCollectionNav part = WebPartToEdit as SPSiteCollectionNav;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (part != null)&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//sync any changes to the web part back to its properties&lt;/span&gt;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;showCreateDateCheckBox.Checked = part.ShowCreateDate;&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;}&lt;/blockquote&gt;And there you have it.  The Create Date checkbox will appear in the properties pane of the WebPart and can be used to turn on and off the display of the Site Create Date in the Site Node text of our Navigation WebPart.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-7293030187007789317?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/_OCbdweKxoA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/7293030187007789317/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=7293030187007789317&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/7293030187007789317?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/7293030187007789317?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/_OCbdweKxoA/site-navigator-released.html" title="Site Navigator Released" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_fcsn-2MxKvM/SUFYJInhPVI/AAAAAAAAABQ/9ZD0bub9wc0/s72-c/SiteNav.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.apollojack.com/2008/12/site-navigator-released.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMDRn45cCp7ImA9WxRXGE0.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-6683716389805688145</id><published>2008-10-20T10:02:00.000-07:00</published><updated>2008-10-23T17:34:37.028-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-23T17:34:37.028-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MA Configuration" /><category scheme="http://www.blogger.com/atom/ns#" term="MIIS" /><category scheme="http://www.blogger.com/atom/ns#" term="MA Join Rules" /><category scheme="http://www.blogger.com/atom/ns#" term="MA Rules Extensions" /><title>Hit or MIIS</title><content type="html">While working out at a client site on their MIIS implementation, occasionally during a sync on one of their MAs, the Identity Manager Application would become almost completely unresponsive. I couldn't start or stop the running of an MA, execute a Preview, complete an MV Search, perform any manual Joins or Disconnections. It was all very frustrating, I would have to wait a few minutes until MIIS came back from the abyss to continue my work. The only other information that I had was from performing a SQL Profiler Trace. MIIS was definitely working on something, but what and why? &amp;lt;spoiler&amp;gt;The Answer: it has to do with the Joining activity that MIIS does while sync'ing an object.&amp;lt;/spoiler&amp;gt; So, here's a little more background...&lt;br /&gt;&lt;br /&gt;While configuring a Management Agent, you are given the ability to define rules that MIIS can use to determine if the object that its currently looking at should be linked to user data that it already has from other systems. This can be done by simply going to the Configure Join and Projection Rules in the Metaverse Designer and clicking on the New Join Rule button at the bottom:&lt;br /&gt;&lt;p align="center"&gt;&lt;a href="http://4.bp.blogspot.com/_fcsn-2MxKvM/SQDA1whuu0I/AAAAAAAAAAw/IRJoKz0f0m0/s1600-h/JoinAndProjectionRules.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5260416394560715586" style="CURSOR: hand" alt="" src="http://4.bp.blogspot.com/_fcsn-2MxKvM/SQDA1whuu0I/AAAAAAAAAAw/IRJoKz0f0m0/s400/JoinAndProjectionRules.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;In its simplest form, a Join Rule can be designed that directly correlates data in the source with data in MIIS. For example, if the First and Last Name are the same, join the identities together:&lt;br /&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;a href="http://3.bp.blogspot.com/_fcsn-2MxKvM/SQDB1RavwFI/AAAAAAAAAA4/tEiVvHiJyRs/s1600-h/NewDirectFN%2BLNJoin.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5260417485721550930" style="WIDTH: 400px; CURSOR: hand; HEIGHT: 325px" alt="" src="http://3.bp.blogspot.com/_fcsn-2MxKvM/SQDB1RavwFI/AAAAAAAAAA4/tEiVvHiJyRs/s400/NewDirectFN%2BLNJoin.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;On the backend, MIIS is executing a query against the Metaverse table to get all of the object_ids of user's with data matching the join criteria:&lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;select distinct [mms_metaverse].object_id from [mms_metaverse] with (holdlock) where (([&amp;lt;MVAttributeName&amp;gt;] =N'&amp;lt;CSAttributeValue&amp;gt;'))&lt;/em&gt;&lt;/blockquote&gt;So if we are sync'ing an individual named Joe Smith, we get a query like (and, yes, there really are both sets of parentheses around each expression):&lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;select distinct [mms_metaverse].object_id from [mms_metaverse] with (holdlock) where (([givenName] =N'Joe')) and (([sn] =N'Smith))&lt;/em&gt;&lt;/blockquote&gt;It will then run the following series of queries to build a portfolio about every object_id returned:&lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;exec mms_getmvsvall_xlock @mvobjid = '&amp;lt;object_id&gt;';&lt;br /&gt;exec mms_getmvmulti @mvobjid = '&amp;lt;object_id&gt;';&lt;br /&gt;exec mms_getmvrefasobjid @mvobjid = '&amp;lt;object_id&gt;';&lt;/em&gt;&lt;/blockquote&gt;Once MIIS has all of this data, it can join with an existing identity for Joe Smith, if one is found. In this scenario, if more than one Joe Smith is found, MIIS will consider this a Non-match and move onto the next join rule. It will continue to execute the join rules one after the other, in turn, until either a join is made or it reaches the end of the list.  If no join is made, MIIS will then move onto projection, if this option has been defined.&lt;br /&gt;&lt;br /&gt;Now, In an actual deployment these join scenarios are usually a little more complicated. To resolve a more complicated search/match, we usually have to go out to our rules extension code. There are two places you can inject code during the join procedure. The first of these is done by using the &lt;em&gt;Rules extension &lt;/em&gt;mapping type. This will allow you to add some additional logic around the attribute equivalency search. Here is what I mean... you are trying to join based on Social Security Number and the source system has SSNs stored as 123-456-789 but MIIS has it stored as 123456789, while these two are not technically equivalent if doing a direct evaluation, we can add code to ensure that evaluation is done "correctly" via code executed in the MapAttributesForJoin Method.&lt;br /&gt;&lt;br /&gt;The second place we can inject code is to pick the proper join out of the X number of candidates found by the Join search. So continuing from our example above, if we have defined a join based on SSN, but our data tends to be pretty dirty and multiple people have the same SSN. We have ensured that our SSN matching is performed properly above in the MapAttributesForJoin by reformatting the data, but the match/search logic finds 5 people that could potentially match my source SSN of 123-456-789. We can add additional code in the ResolveJoinSearch method to determine, based on other data elements, say last name, that number 3 of the 5 people found is the right individual to join with.&lt;br /&gt;&lt;br /&gt;So, here is a more real world example. What if we want to join people base on their birth date with a last name or previous last name match? In this case we will have to go out to code to determine whether a join candidate can be found. We would start by creating a join rule based on birth date:&lt;br /&gt;&lt;p align="center"&gt;&lt;a href="http://4.bp.blogspot.com/_fcsn-2MxKvM/SQDDMZ2EwkI/AAAAAAAAABI/aWcmnajKYvw/s1600-h/NewExtensionDOBJoin.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5260418982632276546" style="WIDTH: 400px; CURSOR: hand; HEIGHT: 325px" alt="" src="http://4.bp.blogspot.com/_fcsn-2MxKvM/SQDDMZ2EwkI/AAAAAAAAABI/aWcmnajKYvw/s400/NewExtensionDOBJoin.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;We have decided to use a &lt;em&gt;Mapping Type&lt;/em&gt; of &lt;em&gt;Rules extension&lt;/em&gt; to allow us to go out to code to reformat the birth date to ensure that it matches the format in MIIS. In our rules extension, MIIS would be looking for an entry point of "cd.person#1:mccdDOB-&gt;mccdDOB" in the MapAttributesForJoinMethod:&lt;br /&gt;&lt;blockquote style="PADDING-RIGHT: 15px; PADDING-LEFT: 15px; PADDING-BOTTOM: 15px; PADDING-TOP: 15px; BACKGROUND-COLOR: #cccccc"&gt;switch (FlowRuleName)&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;case "cd.person#1:mccdDOB-&gt;mccdDOB":&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;if ( csentry["mccdDOB"].IsPresent )&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//reformat the dob with style used in the MV&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;values.Add( System.Convert.ToDateTime(csentry["mccdDOB"].StringValue).ToString("yyyy-MM-dd") );&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;break;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;default:&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;throw new EntryPointNotImplementedException();&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;We have also selected the &lt;em&gt;Use rules extension to resolve&lt;/em&gt; option. This will allow us to add code to check current and previous last names against those individuals found with the same birth date. This is done using the following code in the ResolveJoinSearch Method:&lt;br /&gt;&lt;blockquote style="PADDING-RIGHT: 15px; PADDING-LEFT: 15px; PADDING-BOTTOM: 15px; PADDING-TOP: 15px; BACKGROUND-COLOR: #cccccc"&gt;&lt;span style="color:#006600;"&gt;//set index of final join candidate to -1 to indicate no join found&lt;/span&gt;&lt;br /&gt;imventry = -1;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#006600;"&gt;//create a variable to keep our place in the loop&lt;/span&gt;&lt;br /&gt;int curIndex = 0;&lt;br /&gt;&lt;br /&gt;switch (joinCriteriaName)&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;case "cd.student#1":&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//loop through each person to check current/prev last name&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;foreach (MVEntry mventry in rgmventry)&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;if ( csentry["sn"].IsPresent &amp;amp;&amp;amp; mventry["sn"].IsPresent)&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//try to join on last name&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;if ( csentry["sn"].StringValue == mventry["sn"].StringValue )&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//its a match, return the index of this individual&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;imventry = curIndex;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;else if ( csentry["prevSn"].IsPresent &amp;amp;&amp;amp; mventry["sn"].IsPresent)&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//try to join on previous last name&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;if ( csentry["prevSn"].StringValue == mventry["sn"].StringValue )&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//its a match, return the index of this individual&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;imventry = curIndex;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//we are moving to the next object, increment the counter&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;curIndex++;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;break;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;default:&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;throw new EntryPointNotImplementedException();&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#006600;"&gt;//return index of individual found&lt;/span&gt;&lt;br /&gt;return imventry;&lt;br /&gt;&lt;/blockquote&gt;So, now that we have all of the basics of joining down, we can get back to the problem.  Did you catch it?  When MIIS is performing the join search, it executes a set of stored procedures to get all of the data about the matching Metaverse objects using an exclusive lock, locking up our Metaverse table from any other reads or updates until the search is complete. This usually isn't a problem because this process happens so quickly you usually won't notice it. With that said, be very careful not to create inefficient join rules that return more than a few results. If more than a few records need to be returned and evaluated, not only will being to see a degradation in the UI response of Identity Manager, it will also take exponentially longer for the MA to complete.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-6683716389805688145?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/xwMrqCu40XQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/6683716389805688145/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=6683716389805688145&amp;isPopup=true" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/6683716389805688145?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/6683716389805688145?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/xwMrqCu40XQ/hit-or-miis.html" title="Hit or MIIS" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_fcsn-2MxKvM/SQDA1whuu0I/AAAAAAAAAAw/IRJoKz0f0m0/s72-c/JoinAndProjectionRules.jpg" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://www.apollojack.com/2008/10/hit-or-miis.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQDRXc9cSp7ImA9WhZQFU4.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-6064078889235094037</id><published>2008-10-16T18:29:00.000-07:00</published><updated>2011-04-22T20:46:14.969-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-22T20:46:14.969-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="XML" /><category scheme="http://www.blogger.com/atom/ns#" term="Widgets" /><category scheme="http://www.blogger.com/atom/ns#" term="Gadgets" /><category scheme="http://www.blogger.com/atom/ns#" term="Google" /><category scheme="http://www.blogger.com/atom/ns#" term="HTML" /><title>Creating a Scrolling List Gadget</title><content type="html">One of the most important distractions for me as I develop is my music, it helps to keep me focused. In an effort to share that, I added a widget to the right of my blog that shows a list of the music that I am "currently" listening to. Not finding a good alternative, I simply used a link list widget and inserted a couple of the songs from my current playlist. Well.... not being satisfied with the geek factor, what I really wanted was something more dynamic, a kind of scrolling list, a music reel or marquee, if you will. So I set out to find out how to make my own Blogger Widget....&lt;br /&gt;
&lt;br /&gt;
I started with the Blogger help files:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://help.blogger.com/bin/answer.py?answer=53219"&gt;How do I create new widgets for other people to add to their layouts?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://help.blogger.com/bin/answer.py?answer=46995"&gt;Widget Tags for Layouts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://help.blogger.com/bin/answer.py?answer=46888&amp;amp;ctx=sibling"&gt;Page Elements Tags for Layouts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://help.blogger.com/bin/answer.py?answer=47270#links"&gt;Layouts Data Tags&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;However, I found these a little limiting. I expanded my search and found that, as many others have done, the easiest way to do this to create a new &lt;a href="http://code.google.com/apis/gadgets/docs/dev_guide.html"&gt;Google Gadget&lt;/a&gt;. And better yet, once our Gadget is ready, Google will even host it for us on their &lt;a href="http://code.google.com/apis/gadgets/docs/tools.html#GGE"&gt;GGE&lt;/a&gt; (or for those of us looking for more features at &lt;a href="http://code.google.com/hosting/createProject"&gt;Google Code&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;A Gadget consists of a xml file with three basic elements:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;ModulePrefs&lt;content&gt;&lt;/li&gt;
&lt;li&gt;UserPref&lt;userprefs&gt;&lt;/li&gt;
&lt;li&gt;Content&lt;moduleprefs&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;And looks something like this...&lt;/p&gt;&lt;blockquote style="PADDING-RIGHT: 15px; PADDING-LEFT: 15px; PADDING-BOTTOM: 15px; PADDING-TOP: 15px; BACKGROUND-COLOR: #cccccc"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8" ?&amp;gt;&lt;br /&gt;
&amp;lt;Module&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;ModulePrefs title="" description="" height="" width="" thumbnail="" screenshot="" author_email="" author="" title_url=""&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;!-- all of the following ModulePref Elements are optional --&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;Locale lang="" language_direction="" messages="" country="" /&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;Link rel="" href="" method="" /&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;Require feature=""&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;Param name=""&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/Require&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;Optional feature=""&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;Param name=""&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/Optional&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;Preload href="" authz="none(default),signed,oauth" /&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;Icon mode="" type=""&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;!--base64 encoded data needed when using mode attribute--&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;!--can also use url to icon file if mode attribute is not used--&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/Icon&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/ModulePrefs&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;UserPref name="userPref1" display_name="Example" datatype="string(default),bool,enum,hidden,list,location" urlparam="" &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; required="true,false(default)" default_Value="" /&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;UserPref name="UserPref2" display_name="stringExample" /&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;UserPref name="userPref3" display_name="enumExample" datatype="enum" default_value="A"&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;EnumValue value="A" display_value="Alpha"&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;EnumValue value="B" display_value="Beta"&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;EnumValue value="G" display_value="Gamma"&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/UserPref &amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;Content type="html,url" href="" /&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;![CDATA[&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;!--All the html and javascript needed to get the job done --&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;!--CDATA section only needed if the content type is html--&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;]]&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/Content&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/Module&amp;gt;&lt;/blockquote&gt;A couple of things to keep in mind before you begin. Blogger will provide a user setting for Height and Title by default. List Items can only be Added and Removed, in other words no Edit functionality. To change an entry, it will have to be removed and recreated. Further, it will host your Gadget inside of an iframe, so you will lose any styles applied to the blog. I have tried to compensate for this in my design below. Also, a &amp;lt;div&amp;gt; tag will be added with a class of widget-content and a black border. It will also add scroll bars, if necessary. &lt;br /&gt;
&lt;br /&gt;
I wanted consumer's of my Gadget to be able to set the following options:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Number of Items to Show - integer from 1 to 99,999&lt;/li&gt;
&lt;li&gt;Time to wait before Scrolling (in seconds) - integer from 1 to 99,999&lt;/li&gt;
&lt;li&gt;Content Font Style Definition&lt;/li&gt;
&lt;li&gt;List of Items&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Arriving at a simple UserPrefs section that looks like...&lt;/p&gt;&lt;blockquote style="PADDING-RIGHT: 15px; PADDING-LEFT: 15px; PADDING-BOTTOM: 15px; PADDING-TOP: 15px; BACKGROUND-COLOR: #cccccc"&gt;&amp;lt;UserPref name="myNumItems" display_name="Items to Show" /&amp;gt;&lt;br /&gt;
&amp;lt;UserPref name="myTimer" display_name="Time to Scroll" /&amp;gt;&lt;br /&gt;
&amp;lt;UserPref name="myStyle" display_name="Content Font Style" default_value="8pt Georgia" /&amp;gt;&lt;br /&gt;
&amp;lt;UserPref name="myList" display_name="List of Items" datatype="list" /&amp;gt;&lt;/blockquote&gt;&lt;p&gt;You could add additional style items to give user's more display flexibility, things like color, line size, padding, etc. Finally, I took a stab at the CDATA portion of the Content element. After several rounds of modifications, saves, publishing and testing on my &lt;a href="http://www.google.com/ig"&gt;iGoogle&lt;/a&gt; page, I arrived at the following code:&lt;/p&gt;&lt;blockquote style="PADDING-RIGHT: 15px; PADDING-LEFT: 15px; PADDING-BOTTOM: 15px; PADDING-TOP: 15px; BACKGROUND-COLOR: #cccccc"&gt;&amp;lt;div id="content_div"&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color:#006600;"&gt;// Get UserPrefs Options&lt;/span&gt;&lt;br /&gt;
var prefs = new _IG_Prefs(); &lt;span style="color:#006600;"&gt;//new gadgets.Prefs();&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color:#006600;"&gt;// Get Details of UserPrefs&lt;/span&gt;&lt;br /&gt;
var items = prefs.getArray("myList");&lt;br /&gt;
var style = prefs.getString("myStyle");&lt;br /&gt;
var numToShow = 99999; &lt;br /&gt;
var timer = 99999;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color:#006600;"&gt;//validate entries&lt;/span&gt;&lt;br /&gt;
if (!isNaN(prefs.getString("myNumItems")))&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;numToShow = new Number(prefs.getString("myNumItems"));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if (numToShow &amp;gt; 99999)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;numToShow = 99999&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if (!isNaN(prefs.getString("myTimer")))&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;timer = new Number(prefs.getString("myTimer"));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if (timer &amp;gt; 99999)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;timer = 99999;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color:#006600;"&gt;// keep track of where we are in our loop&lt;/span&gt;&lt;br /&gt;
var curIndex = 0;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color:#006600;"&gt;// load list once for initial display&lt;/span&gt;&lt;br /&gt;
displayList();&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color:#006600;"&gt;// reload list after delay&lt;/span&gt;&lt;br /&gt;
setInterval("displayList()", timer * 1000);&lt;br /&gt;
&lt;br /&gt;
function displayList()&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;// Build HTML to show the user&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;var html = "&amp;lt;table id='content-table' cellPadding='1px' border='0'&amp;gt;";&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;// Loop through and display items&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;if (items.length &amp;gt; 0)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;var loopUntil = numToShow;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;var itemToShow = new Number(curIndex);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;// if user has set the number to show greater than the number of items we&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;// have in our list, only loop through the number in the list&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (items.length &amp;lt; loopUntil)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;loopUntil = items.length;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//loop through our items, keeping track of where we are and what needs to be shown&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;for (var i = 0; i &amp;lt; loopUntil; i++)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//if we have moved past the end of the list start back at the beginning&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (itemToShow &amp;gt;= items.length)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;itemToShow = 0;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;html += "&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;" + items[itemToShow] + "&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;"; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;itemToShow++; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;// Start loop at the next one in the list&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;curIndex++;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (curIndex &amp;gt;= items.length)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;curIndex = 0;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;html += "&amp;lt;/table&amp;gt;"&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;document.getElementById("content_div").innerHTML = html;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style="color:#006600;"&gt;//load in our style element&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;var cells=document.getElementsByTagName("td");&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;for (var i=0; i &amp;lt; cells.length; i++)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;cells[i].style.font = style;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/blockquote&gt;&lt;br /&gt;
Don't be surprised if Google warns you about missing elements, like thumbnail and width, when you publish your Gadet. I was able to accept the warning and still publish successfully.&lt;br /&gt;
&lt;p&gt;I then went to import this Gadget to my blog using the url that Google gave me during publishing, &lt;a href="http://hosting.gmodules.com/ig/gadgets/file/102621166658384583871/scrolling-list.xml"&gt;http://hosting.gmodules.com/ig/gadgets/file/102621166658384583871/scrolling-list.xml&lt;/a&gt;. Next, using the Edit HTML tab in the Layout section of my blog, I was able to remove the border around my Gadget and change the padding to the left of the Gadget by checking the Expand Widget Definitions and locating the &amp;lt;div&amp;gt; tag just before my Gadget. I also set the scrolling attribute on the iFrame to no. While changing the Font Style in user settings, I will sometimes get JavaScript errors, however, in my mind, the benefits here outweigh the issue. &lt;/p&gt;&lt;p&gt;You can see the fruits of my labor over to the right, titled "Currently Developing To...".....Wait for it.....&lt;br /&gt;
&lt;br /&gt;
Let me know what you think and feel free to add the Gadget to your own site! Happy blogging!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-6064078889235094037?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/l6yEfgN7-dI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/6064078889235094037/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=6064078889235094037&amp;isPopup=true" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/6064078889235094037?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/6064078889235094037?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/l6yEfgN7-dI/creating-scrolling-list-gadget.html" title="Creating a Scrolling List Gadget" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total><feedburner:origLink>http://www.apollojack.com/2008/10/creating-scrolling-list-gadget.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08HSH8_fSp7ImA9WxRXEUo.&quot;"><id>tag:blogger.com,1999:blog-3265068911303773094.post-4915597556909186240</id><published>2008-10-16T10:31:00.000-07:00</published><updated>2008-10-16T10:57:19.145-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-16T10:57:19.145-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="About Me" /><category scheme="http://www.blogger.com/atom/ns#" term="About Ensynch" /><title>Welcome!</title><content type="html">I have been a developer for over 10 years, spending the last 6 of those as a consultant working for the world-class IT provider, &lt;a href="http://www.ensynch.com/"&gt;&lt;em&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Ensynch&lt;/span&gt;&lt;/em&gt;&lt;/a&gt;. While working for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Ensynch&lt;/span&gt;, I have had the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;privilege&lt;/span&gt; of being exposed to an extensive portfolio of technologies. Its my objective to begin a blog about my adventures. And I have some very big shoes to fill here, following in the footsteps of those folks you see to the right. Getting into the blogging game a little late, my first (second?) post will be, not &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;coincidentally&lt;/span&gt;, about creating this blog.&lt;br /&gt;&lt;br /&gt;Based out of Tempe, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Ensynch&lt;/span&gt; has both a professional services and a talent solutions arm. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Ensynch&lt;/span&gt; has been awarded with such prestigious &lt;a href="http://www.ensynch.com/co_pr_awards.aspx"&gt;&lt;em&gt;awards&lt;/em&gt;&lt;/a&gt; as Microsoft's West Region Partner of the Year and The Business Journal's #1 Phoenix Computer Consultant company. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Ensynch&lt;/span&gt; provides expertise in several core areas, including, Identity &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_7"&gt;Management&lt;/span&gt;, Portals and Collaboration, Systems &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_8"&gt;Management&lt;/span&gt;, Infrastructure Optimization, Unified Communications and Application Development/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;Lifecycle&lt;/span&gt; &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_10"&gt;Management&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;So without further ado, here goes.....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3265068911303773094-4915597556909186240?l=www.apollojack.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ApolloJack/~4/der8NOwaEh4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.apollojack.com/feeds/4915597556909186240/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3265068911303773094&amp;postID=4915597556909186240&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/4915597556909186240?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3265068911303773094/posts/default/4915597556909186240?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/ApolloJack/~3/der8NOwaEh4/welcome.html" title="Welcome!" /><author><name>Rebecca Croft</name><uri>http://www.blogger.com/profile/06968410533499869665</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.apollojack.com/2008/09/welcome.html</feedburner:origLink></entry></feed>

