<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"
>

<channel>
	<title>Will Norris &#187; shibboleth</title>
	<atom:link href="http://willnorris.com/tag/shibboleth/feed" rel="self" type="application/rss+xml" />
	<link>http://willnorris.com</link>
	<description>Thoughts on Identity, OpenID, WordPress, and Life</description>
	<lastBuildDate>Tue, 26 Jan 2010 16:25:05 +0000</lastBuildDate>
	
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
		<item>
		<title>Java OpenID Library - Target Audience</title>
		<link>http://willnorris.com/2009/12/java-openid-library-target-audience</link>
		<comments>http://willnorris.com/2009/12/java-openid-library-target-audience#comments</comments>
		<pubDate>Thu, 24 Dec 2009 20:02:48 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[identity]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[shibboleth]]></category>

		<guid isPermaLink="false">http://willnorris.com/?p=895</guid>
		<description><![CDATA[One of the decisions that has to be made, or at least considered, early in the design of any software project is identifying your target audience.  This is especially true of libraries that are designed to be integrated into other applications.  Who do you expect to be using this library, and how do [...]

<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2009/11/java-openid-library-design-message-handling' rel='bookmark' title='Permanent Link: Java OpenID Library Design - Message Handling'>Java OpenID Library Design - Message Handling</a></li>
<li><a href='http://willnorris.com/2009/11/java-openid-library-configuration-and-custom-messages' rel='bookmark' title='Permanent Link: Java OpenID Library - Configuration and Custom Messages'>Java OpenID Library - Configuration and Custom Messages</a></li>
<li><a href='http://willnorris.com/2007/04/shibboleth-definition' rel='bookmark' title='Permanent Link: Shibboleth definition'>Shibboleth definition</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<p>One of the decisions that has to be made, or at least considered, early in the design of any software project is identifying your target audience.  This is especially true of libraries that are designed to be integrated into other applications.  Who do you expect to be using this library, and how do you expect them to make use of it?  Is it something like <a href="http://logging.apache.org/log4j/">log4j</a> that can be dropped into place and used with just a few lines of additional code?  Or is it something that is intended to be integrated into a larger system, requiring the developer using the library to provide additional logic and business rules to get things working?  Something that might require a non-trivial amount of effort, depending on the needs of the use-case.  There is no right or wrong answer, and oftentimes it&#8217;s somewhere in between, but it&#8217;s something that must be considered.</p>

<p>Some of the best software libraries I&#8217;ve used address both ends of the spectrum.  There&#8217;s a common adage in software development (and I&#8217;m sure it goes back farther than that): &#8220;make the common things easy, and the hard things possible&#8221;.  First, you don&#8217;t want to make things any harder than necessary for the majority of users that are just using the basic functionality of a library.  If they don&#8217;t care about customizing and tweaking every little aspect of it, then the way they interact with the library should be relatively simple and straightforward.  But for those users that have unique needs, the library should allow them to configure it in such a way to accommodate that.  It is certainly my goal to address both extremes in the Shibboleth OpenID library, but it will happen in phases.</p>

<p>The first phase will address the edge-cases, those users of the library that tend to have unique needs and requirements.  That may seem backwards, but I assure you it isn&#8217;t.  First of all, the really practical reason for starting here is that Shibboleth is itself an edge case.  The reason I chose not to use the existing Java OpenID libraries in the first place was that they didn&#8217;t adequately conform to the way Shibboleth needed them to work.  But from a design perspective, I&#8217;ve found that this approach tends to yield better results anyway.</p>

<h2>Small Pieces Loosely Coupled</h2>

<p>I&#8217;ve learned that in order to make a system really flexible and modular, it&#8217;s best to architect it that way from the very beginning.  You have to decide where the logical divisions of labor are within the system, and then translate that into the code itself.  Each component should be relatively self-contained, it&#8217;s purpose should be clear, and its interface (the way it interacts with other components) should be separated from its actual implementation.  Sometimes these components are obvious, and there are clear places where the code should be divided.  But more often than not, its a judgement call.  Architecture is often harder than actual construction, whether you&#8217;re talking about software or brick and mortar.  It requires a lot of creativity because you&#8217;re often working from a blank canvas, but it also requires that your plans are grounded in what is actually possible.  Architectural plans are worthless if they can&#8217;t actually be implemented in the real world in a practical way.  By no means do I think that I&#8217;ve found the best architecture for this library, because it&#8217;s always subjective.  Fortunately, I&#8217;ve had <a href="http://opensaml.org/">similar libraries</a> that I&#8217;ve borrowed from heavily for inspiration, as well as much smarter developers that I work with to bounce ideas off of.</p>

<p>At its core, this library is an OpenID messaging library.  It is capable of converting between generic HTTP messages and strongly typed OpenID objects that developers can work with.  My last two posts have talked about this in detail.  The library also provides the additional logic for implementing the OpenID specification, things like Diffie Hellman key exchange and OpenID message signing.  What the library does <strong>not</strong> do is tell you how you must compose these pieces into a working system.  That&#8217;s because there isn&#8217;t just one way to do it.  It greatly depends on the application that is wanting to add OpenID support.  If you&#8217;re using a Java framework like <a href="http://tapestry.apache.org/">Tapestry</a> or <a href="http://java.sun.com/javaee/javaserverfaces/">JSF</a>, perhaps you have other processing that happens to the message before the OpenID library gets involved.  How does the user get authenticated and where do the user attributes come from?  I have no idea&#8230; that&#8217;s up to your application to decide.  At this level, the library makes no assumptions (or at least as few as possible) about how all of these small pieces should be coupled together.</p>

<p>If this sounds like a lot of work left up to the user just for something as simple as OpenID, you&#8217;re right&#8230; it is a lot of work.  But when you really need that level of control, it&#8217;s important that the library support that.</p>

<h2>Addressing the Common Case</h2>

<p>So what about everyone else, all the &#8220;mere mortals&#8221; who <em>don&#8217;t</em> need that much control, and just want to add OpenID support to some application using the default configuration?  At a high level, I&#8217;d love to have a Servlet Filter that you can drop in front of your application, configure a few small things, and have it <strong>just work</strong> as an OpenID relying party.  I&#8217;ve always been a huge fan of the Tapestry framework, so I&#8217;d love to have a Tapestry component that can be dropped in just as easily.  All of these things are possible by building a layer that sits on top of those individual components in the library, and arranges them in a prescribed way.</p>

<p>Now, I don&#8217;t anticipate that a drop-in Servlet Filter will ever be a part of the core library, because I don&#8217;t think it belongs there.  It would be a separate deliverable unto itself that simply relies on the library to do all of OpenID work.  This also means that the Filter wouldn&#8217;t necessarily need to come from me, anyone could write it and make it available.  I don&#8217;t imagine that the core library itself will ever have everything that the &#8220;common case&#8221; users will need.  And I&#8217;m okay with that, because I&#8217;m not building an OpenID product, I&#8217;m building an OpenID library.</p>

<h2>Current Status</h2>

<p>This is by no means a complete picture of the Shibboleth OpenID library, but it should give you a rough idea.  It identifies some of the larger components of the libraries, and some of the interdependencies.</p>

<p><img src="http://farm3.static.flickr.com/2518/4211756452_3e7d278f3a.jpg" alt="OpenID Java Software Stack (v1)" width="364" height="256" /></p>

<p>The orange blocks are pieces that are basically complete and present in the current library.  All of the message handling is complete for OpenID 2.0 message, as well as three of the most popular message extensions (SReg, AX, and PAPE).  Additionally, association management is done, and a very simple AssociationStore is provided (though it needs a little improvement).  The security layer is complete insofar as signing and verifying signed messages.  The yellow blocks represent pieces that are not yet complete, but will be included in the core library in the future.  The discovery component is still up in the air a little bit because it&#8217;s not completely clear if we&#8217;ll be using XRD, XRDS, or both.  The portions of the security layer that depend on discovery are, of course, waiting on the completion of the discovery stack.  Those pieces include everything that an application would need to construct an OpenID provider or relying party.  They implement the full OpenID protocol.</p>

<p>But those components alone leave a lot to be filled in by the application using the library.  It says nothing about how an incoming HttpServletRequest object is converted into an OpenID Message.  The application would be responsible for instantiating the specific objects and wiring them together to actually get a working AssociationManager.  And for applications that wish to have control over these specific aspects of an OpenID flow, this is a good thing.  The next layer up on the stack however, the yellow &#8220;Managers&#8221; block, will provide simple Manager objects that wire things together in a prescribed way.  Most users of the library will deal with the Manager layer, and probably nothing else.  Only when they have specific needs will it be necessary to dig any deeper.</p>

<p>Now this last layer is actually nothing special&#8230; it&#8217;s a very common pattern, and both <a href="http://openid4java.org/">OpenID4Java</a> and <a href="http://code.google.com/p/joid/">Joid</a> work in very similar ways.  I point it out only to note that while this layer will be part of the core library in a future release, it isn&#8217;t right now.  Much of the code that will likely make up these components has already been written, but in the form of the <a href="https://spaces.internet2.edu/display/SHIB2/IdP+OpenID">Shibboleth IdP extension</a>.  For the last few months I&#8217;ve been simultaneously building both a generic OpenID library, as well as an actual product that makes use of the library.   One of the tougher ongoing challenges while doing this is in deciding which of the two projects a particular bit of code goes into.  Much of the time it&#8217;s clear, but when in doubt, I&#8217;ll put something into the Shibboleth extension rather than the library.  If anything, I want to err on the side of keeping the library &#8220;pure&#8221; so to speak.  To not accidentally bake any assumptions into the library itself that might limit its flexibility.  One of my focuses after the holidays will be in identifying which pieces need to be refactored from the Shibboleth extension back into the core library in order to build out that management layer.</p>

<p>(And in case it&#8217;s not clear, the final layer in grey in the stack above are other pieces that will make use of the OpenID library, but will likely not be part of the library itself.)</p>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2009/11/java-openid-library-design-message-handling' rel='bookmark' title='Permanent Link: Java OpenID Library Design - Message Handling'>Java OpenID Library Design - Message Handling</a></li>
<li><a href='http://willnorris.com/2009/11/java-openid-library-configuration-and-custom-messages' rel='bookmark' title='Permanent Link: Java OpenID Library - Configuration and Custom Messages'>Java OpenID Library - Configuration and Custom Messages</a></li>
<li><a href='http://willnorris.com/2007/04/shibboleth-definition' rel='bookmark' title='Permanent Link: Shibboleth definition'>Shibboleth definition</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2009/12/java-openid-library-target-audience/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Java OpenID Library Design - Message Handling</title>
		<link>http://willnorris.com/2009/11/java-openid-library-design-message-handling</link>
		<comments>http://willnorris.com/2009/11/java-openid-library-design-message-handling#comments</comments>
		<pubDate>Sat, 14 Nov 2009 00:16:52 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[identity]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[internet2]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[joid]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[openid4java]]></category>
		<category><![CDATA[shibboleth]]></category>

		<guid isPermaLink="false">http://willnorris.com/?p=888</guid>
		<description><![CDATA[This past June I contracted with Internet2 to work on adding OpenID support to the Shibboleth Identity Provider.  I had actually started to work on this over a year prior while working at USC.  At the time there were (and still are) two primary OpenID libraries in Java, Verisign&#8217;s JOID, and Sxip&#8217;s OpenID4Java. [...]

<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2009/11/java-openid-library-configuration-and-custom-messages' rel='bookmark' title='Permanent Link: Java OpenID Library - Configuration and Custom Messages'>Java OpenID Library - Configuration and Custom Messages</a></li>
<li><a href='http://willnorris.com/2009/12/java-openid-library-target-audience' rel='bookmark' title='Permanent Link: Java OpenID Library - Target Audience'>Java OpenID Library - Target Audience</a></li>
<li><a href='http://willnorris.com/2005/03/classnotfound' rel='bookmark' title='Permanent Link: A class needed by class &lt;&#8230;&gt; cannot be found: org/apache/tools/ant/Task'>A class needed by class &lt;&#8230;&gt; cannot be found: org/apache/tools/ant/Task</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<p>This past June I contracted with <a href="http://internet2.edu/">Internet2</a> to work on adding OpenID support to the <a href="http://shibboleth.internet2.edu/">Shibboleth</a> Identity Provider.  I had actually started to work on this over a year prior while working at USC.  At the time there were (and still are) two primary OpenID libraries in Java, Verisign&#8217;s <a href="http://code.google.com/p/joid/">JOID</a>, and Sxip&#8217;s <a href="http://code.google.com/p/openid4java/">OpenID4Java</a>.  I spent a fair amount of time looking at both libraries, but ultimately decided they weren&#8217;t going to work for what Shibboleth needed.  There were architectural issues with the existing libraries, which I pointed out in <a href="http://groups.google.com/group/openid4java/browse_thread/thread/f0775348b3b7f3f/f93d22fe21a6e37e">my post</a> to the OpenID4Java mailing list.  But there were also significant design decisions that I felt could be improved upon, so I began work on a new OpenID library in Java.  Now that this library is nearing a usable state, I wanted to talk about some of the architectural decisions that were made, and how it differs from the existing Java libraries for OpenID.</p>

<p>Let me first preface this by clarifying that I&#8217;m not saying the existing OpenID libraries are not usable.  Quite the contrary, I know that the OpenID4Java library is used for AOL&#8217;s OpenID provider, on Google&#8217;s Blogger, as part of Sun&#8217;s <a href="https://opensso.dev.java.net/">OpenSSO</a>, and countless other projects.  Additionally, JOID powers Verisign&#8217;s very usable <a href="https://pip.verisignlabs.com/">PIP</a>.  There is no question that they work for many use cases.  However, they lack the clean architecture I was looking for, which can really only be corrected by starting from a blank canvas.</p>

<p>(I&#8217;m not sure how many posts this will take, or how sensical the order of things will be, but better to go ahead and get it written down in <em>some</em> form.)</p>

<h2>Message Handling Flow</h2>

<p>One of the most immediate differences you&#8217;ll see in the Internet2 library is the very clear separation of logic in the message handling code.  I wanted the core message objects to be simple Java beans that provide access to strongly typed properties, and nothing more.  When I&#8217;m processing an OpenID message, I don&#8217;t want to be thinking about how that message was encoded during transit.  Additionally, I don&#8217;t want to duplicate code if at all possible, so there needs to be one very clear place where any particular process is implemented.  To achieve this, messages are transformed into three distinct formats as they are being processed.</p>

<p>When a message comes in to an OpenID provider, it is in some kind of transport specific format.  Typically that will be a URL-encoded string that is taken either from an HTTP POST request body, or from an HTTP GET request query string.  Alternately, it may be a Map retrieved by calling <a href="http://java.sun.com/javaee/5/docs/api/javax/servlet/ServletRequest.html#getParameterMap()">ServletRequest.getParameterMap</a>.  This transport specific format needs to first be converted into some kind of common intermediary format so that the next step in the process can deal with all messages in the same way, regardless of transport method.  In the Internet2 library, this common format is a ParameterMap.</p>

<h3>ParameterMap</h3>

<p>A <a href="http://svn.middleware.georgetown.edu/view/java-openid/trunk/src/main/java/edu/internet2/middleware/openid/common/ParameterMap.java?view=markup">ParameterMap</a> is simply a <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/LinkedHashMap.html">LinkedHashMap</a> with <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/namespace/QName.html">QName</a> keys, String values, and a little additional logic.  Why QNames for keys?  Aren&#8217;t those for XML?  Yes they are, but they actually work beautifully for OpenID message parameters as well.  You see, an OpenID message is really just a collection of namespace qualified parameters, and can be quite easily represented in XML.  (Yes, this is a little bit of a rabbit trail, but it&#8217;s interesting nonetheless).  Let&#8217;s start with a really simple KVF encoded OpenID message:</p>

<pre><code>openid.ns:http://specs.openid.net/auth/2.0
openid.mode:checkid_setup
openid.claimed_id:http://example.com/
openid.identity:http://example.com/
openid.ns.sreg:http://openid.net/extensions/sreg/1.1
openid.sreg.required:email,fullname
</code></pre>

<p>Yeah it has no signature, etc, but that&#8217;s not the point.  What might this look like in XML?</p>

<pre><code>&lt;message xmlns="http://specs.openid.net/auth/2.0" 
         xmlns:sreg="http://openid.net/extensions/sreg/1.1"&gt;
    &lt;mode&gt;checkid_setup&lt;/mode&gt;
    &lt;claimed_id&gt;http://example.com/&lt;/claimed_id&gt;
    &lt;identity&gt;http://example.com/&lt;/identity&gt;
    &lt;sreg:required&gt;email,fullname&lt;/sreg:required&gt;
&lt;/message&gt;
</code></pre>

<p>See how cleanly it maps?  This is no accident.  This is a very common pattern for handling namespace qualified parameters.  First you assign your namespace to an alias, then you use that alias as a prefix for any parameters that are part of that namespace.  The simple registration &#8216;required&#8217; parameter name has three parts: there&#8217;s the base parameter name (&#8220;required&#8221;), the namespace alias (&#8220;sreg&#8221;), and the actual namespace URI which is declared separately (&#8220;http://openid.net/extensions/sreg/1.1&#8221;).  A Java QName object consists of three parts: a namespace URI, a local part, and a namespace prefix.  Slightly different terms, but <strong>exactly</strong> the same concepts.</p>

<p>Okay, so back to our OpenID library.  We&#8217;ve taken our transport specific encoding, passed it through an appropriate <a href="http://svn.middleware.georgetown.edu/view/java-openid/trunk/src/main/java/edu/internet2/middleware/openid/message/encoding/MessageDecoder.java?view=markup">MessageDecoder</a>, and ended up with a ParameterMap.  Before we move on, I want to point out one more thing about the parameters in a ParameterMap.  None of the parameter names contain the &#8220;openid.&#8221; prefix.  This prefix is specific to messages that are encoded using <a href="http://openid.net/specs/openid-authentication-2_0.html#rfc.section.4.1.2">URL Form encoding</a>, since that&#8217;s the only way to identify which parameters are part of the OpenID message.  One of the jobs of the <a href="http://svn.middleware.georgetown.edu/view/java-openid/trunk/src/main/java/edu/internet2/middleware/openid/message/encoding/impl/URLFormCodec.java?view=markup">URLFormCodec</a> is to strip this prefix as messages come in, and add the prefix as messages go out.  The message encoder and decoder is the <strong>only</strong> part of the entire library that knows anything about this prefix, and quite frankly it&#8217;s the only part that should.</p>

<p>Okay, so now that we have our ParameterMap, it needs to be converted into an actual message object, which is the job for a MessageUnmarshaller.</p>

<h3>Unmarshalling messages</h3>

<p><a href="http://svn.middleware.georgetown.edu/view/java-openid/trunk/src/main/java/edu/internet2/middleware/openid/message/io/MessageUnmarshaller.java?view=markup">Message unmarshallers</a> are responsible for taking a ParameterMap and using it to populate a specific kind of message object.  Remember the desire for message objects to have strongly typed properties?  The corresponding unmarshaller for that message type is the one and only place that needs to worry with how the parameter passed on the wire gets converted into that strong type.  For example, <a href="http://svn.middleware.georgetown.edu/view/java-openid/trunk/src/main/java/edu/internet2/middleware/openid/message/AssociationRequest.java?view=markup">AssociationRequest</a> messages may include the Diffie-Hellman public key of the OpenID relying party.  Java provides a very specific object just for that called <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/crypto/interfaces/DHPublicKey.html">DHPublicKey</a>, so that&#8217;s what we want our AssociationRequest object to use.  Parameters can only be passed as strings during transit, so the <a href="http://svn.middleware.georgetown.edu/view/java-openid/trunk/src/main/java/edu/internet2/middleware/openid/message/impl/AssociationRequestUnmarshaller.java?view=markup">AssociationRequestUnmarshaller</a> (and nothing else) is responsible for knowing how to convert that string into a DHPublicKey.</p>

<p>Similarly, Attribute Exchange fetch requests may include a list of required attributes it wants for a user.  These attributes are identified by URIs, so Attribute Exchange does it&#8217;s own aliasing similar to the namespace declarations we saw above.  This way, the &#8220;ax.required&#8221; message parameter need only contain a comma-separated list of attribute aliases rather than the full namespace URIs.  But when you get right down to it, these aliases are just an optimization that is used during transport.  Really all that&#8217;s being represented is a list of attributes URIs.  This is why the <a href="http://svn.middleware.georgetown.edu/view/java-openid/trunk/src/main/java/edu/internet2/middleware/openid/extensions/ax/FetchRequest.java?view=markup">FetchRequest</a> object in the Internet2 library exposes this particular message parameter simply as a List of attribute URIs.  It&#8217;s the <a href="http://svn.middleware.georgetown.edu/view/java-openid/trunk/src/main/java/edu/internet2/middleware/openid/extensions/ax/impl/FetchRequestUnmarshaller.java?view=markup">FetchRequestUnmarshaller</a> that is responsible for taking the AX message parameters, dereferencing the attribute aliases, and populating the FetchRequest object appropriately.</p>

<h3>Reversing the process</h3>

<p>What about returning OpenID response messages?  We just do the same process in reverse.  The message object is passed through an appropriate <a href="http://svn.middleware.georgetown.edu/view/java-openid/trunk/src/main/java/edu/internet2/middleware/openid/message/io/MessageMarshaller.java?view=markup">MessageMarshaller</a> which populates a ParameterMap.  And the ParamerMap is in turn passed through a <a href="http://svn.middleware.georgetown.edu/view/java-openid/trunk/src/main/java/edu/internet2/middleware/openid/message/encoding/MessageEncoder.java?view=markup">MessageEncoder</a> that produces some kind of transport specific format.  That may be a Key-Value form encoded string, as is the case with direct responses, it may be a URL suitable for redirecting the user to, or it may be an HTML response to use for HTML form submission.</p>

<h2>Uniformity over brevity</h2>

<p>Depending on how you separate them, there are roughly nine different message types in the core OpenID 2.0 spec, and for each of these message types, the Internet2 library has five files that handle the processing.  There&#8217;s the message interface, the concrete implementation, the message builder (which I didn&#8217;t actually talk about in this post), the message marshaller, and the message unmarshaller.  At times all these files may seem needlessly verbose, especially when you see that some of them are only a few lines long.  It turns out that this separation doesn&#8217;t necessarily result in more lines of code, just that the code is broken up into smaller chunks.  Besides, the goal here is not conciseness.  The goal is uniformity and predictability in how messages are processed, as well as clean, logical separation of duties.  When every message is processed in exactly the same way, bugs tend to expose themselves much earlier in the process, and strange edge cases are far rarer.  When things are logically separated, it makes the overall architecture much easier to understand.  And perhaps more importantly, it makes it possible to fully understand one part of the library without needing to be concerned with others.  You can go in and look at the code for <a href="http://svn.middleware.georgetown.edu/view/java-openid/trunk/src/main/java/edu/internet2/middleware/openid/security/SecurityUtils.java?view=markup">signing messages</a>, and not have to wade through code dealing with transport encodings.</p>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2009/11/java-openid-library-configuration-and-custom-messages' rel='bookmark' title='Permanent Link: Java OpenID Library - Configuration and Custom Messages'>Java OpenID Library - Configuration and Custom Messages</a></li>
<li><a href='http://willnorris.com/2009/12/java-openid-library-target-audience' rel='bookmark' title='Permanent Link: Java OpenID Library - Target Audience'>Java OpenID Library - Target Audience</a></li>
<li><a href='http://willnorris.com/2005/03/classnotfound' rel='bookmark' title='Permanent Link: A class needed by class &lt;&#8230;&gt; cannot be found: org/apache/tools/ant/Task'>A class needed by class &lt;&#8230;&gt; cannot be found: org/apache/tools/ant/Task</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2009/11/java-openid-library-design-message-handling/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Best Practices with Directed Identity</title>
		<link>http://willnorris.com/2009/08/best-practices-with-directed-identity</link>
		<comments>http://willnorris.com/2009/08/best-practices-with-directed-identity#comments</comments>
		<pubDate>Mon, 03 Aug 2009 00:27:43 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[identity]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[directed identity]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[saml]]></category>
		<category><![CDATA[shibboleth]]></category>

		<guid isPermaLink="false">http://willnorris.com/?p=831</guid>
		<description><![CDATA[Given the current discussion happening right now around federal website cookie policies, and the good response I got from my last post, I wanted to continue talking about directed identity a little bit.  In this post, I want to talk about how directed identity has actually been implemented in projects I&#8217;ve been involved with, [...]

<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2009/07/openid-directed-identity-identifier-select' rel='bookmark' title='Permanent Link: Directed Identity vs Identifier Select'>Directed Identity vs Identifier Select</a></li>
<li><a href='http://willnorris.com/2009/08/a-new-kind-of-openid-proxy' rel='bookmark' title='Permanent Link: A New Kind of OpenID Proxy'>A New Kind of OpenID Proxy</a></li>
<li><a href='http://willnorris.com/2007/03/openid-provider-wish-list' rel='bookmark' title='Permanent Link: OpenID provider wish-list'>OpenID provider wish-list</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<p>Given the current discussion happening right now around federal website <a href="http://blog.ostp.gov/2009/07/24/cookiepolicy/">cookie policies</a>, and the good response I got from my <a href="http://willnorris.com/2009/07/openid-directed-identity-identifier-select">last post</a>, I wanted to continue talking about directed identity a little bit.  In this post, I want to talk about how directed identity has actually been implemented in projects I&#8217;ve been involved with, and what lessons can be learned from that.</p>

<p><span id="more-831"></span></p>

<h2>Shibboleth and SAML</h2>

<p><a href="http://shibboleth.internet2.edu/">Shibboleth</a> is an open source web single sign-on product which is very popular with universities around the world.  It is primarily an implementation of the <a href="http://saml.xml.org/saml-specifications">Security Assertion Markup Language</a> (SAML), but supports other identity protocols as well.  SAML v2 defines a specific type of identifier that may be used to identify a user within a transaction known as a <em>Persistent Identifier</em>.  The name itself does not convey it&#8217;s full meaning, but it is defined as &#8220;a persistent opaque identifier for a principal that is specific to an identity provider and a service provider or affiliation of service providers.&#8221;  This is SAML&#8217;s <em>directed identity</em>.</p>

<p>Shibboleth&#8217;s implementation of persistent identifiers has matured a bit over the years, but the main algorithm remains the same.  At it&#8217;s simplest, the identifier is simply a hash of three things: an identifier for the user, an identifier for the identity provider, and an identifier for the relying party.  Using md5 as our hashing algorithm, and using a few made up values, this would look like:</p>

<pre><code>md5( "jsmith" + "http://idp.example.com/" + "http://sp.example.com/" ) = 
    2f6bc52c7527747eff263f4183c7f402
</code></pre>

<p>When a relying party receives the string &#8220;2f6bc52c7527747eff263f4183c7f402&#8221;, it is completely opaque and reveals nothing about the identity of the user.</p>

<h2>Working with known algorithms</h2>

<p>As I mentioned before, Shibboleth is open source software.  All of our code is publicly available, including <a href="http://svn.middleware.georgetown.edu/view/java-shib-common/branches/REL_1/src/main/java/edu/internet2/middleware/shibboleth/common/attribute/resolver/provider/attributeDefinition/TransientIdAttributeDefinition.java?view=markup">the way that we calculate persistent identifiers</a>.  So how could a relying party use this knowledge to take the above opaque identifier and decipher the identity of the user it belongs to?  Pretty simply, if they have a list of possible usernames, or can reasonably guess them.  A list of usernames is far easier to get than you might imagine from unprotected university LDAP directories.  Then you simply iterate through the list and run the same algorithm until you find the matching hash value.  And even given a population of 30,000 usernames (the approximate number of students at <a href="http://www.usc.edu/">USC</a> where I worked), the following shell script churns through them in about 90 seconds:</p>

<pre><code>~$ date &amp;&amp; for i in `head -n 30000 /usr/share/dict/web2`; 
   do echo $i | md5 &gt;/dev/null; done &amp;&amp; date
Sun Aug  2 16:25:53 PDT 2009
Sun Aug  2 16:27:35 PDT 2009
</code></pre>

<p>To protect against such a brute-force attach to reveal the identity of a user, we added a secret salt to the hashing algorithm.  That way, you can&#8217;t regenerate the hash without also knowing the salt value:</p>

<pre><code>md5( "jsmith" + "http://idp.example.com/" + "http://sp.example.com/" 
    + "my-secret-salt" ) = cf79282c587897fb733d8338fe7bc9c2
</code></pre>

<p>It&#8217;s worth pointing out that, while use of a secret salt prevents a relying party from brute forcing the hash, it in no way prevents the identity provider from doing so, since they do of course know the secret salt.  Though we never ended up needing to do this at USC, we built the tools that would enable us to identify the user a persistent identifier belonged to.  In the event that a relying party reported that a particular user was abusing their system, we wanted to make sure we could identify who it was.</p>

<h2>The realities of deployment</h2>

<p>The above algorithm actually works pretty well for generating unique and secure opaque values for tuples of user, identity provider, and service provider.  But what happens when one of those values change?  At USC, users could request that their username be changed for a variety of reasons, and approximately 300 such requests were made each year.  So using the above algorithm, a username change would change every one of the user&#8217;s generated persistent identifiers.  And the reality is, businesses are often bought out by other businesses.  What happens when &#8220;http://sp.example.com/&#8221; needs to change to &#8220;http://sp.new-company.com/&#8221;?  That will effect the generated persistent identifier for <strong>every</strong> user.  How do you deal with these realities?  There are a number of ways, and I&#8217;ll outline just a few.  There is no one <em>right</em> solution, as the policy and practices of a particular institution will greatly impact their decision of how to address these situations.</p>

<p>Perhaps the simplest option in some respects would be to simply not change which identifiers are used for generating the hash and instead <strong>map the new identifiers</strong> to the old values.  Even if a user&#8217;s username has changed to &#8220;jjones&#8221;, you map it back to &#8220;jsmith&#8221; for the purposes of generated persistent identifiers.  While this allows a deployment to continue using the same hashes, it does introduce the burden of maintaining this map of identifiers.  And what is the institution&#8217;s policy with regards to re-issuing identifiers?  If &#8220;jsmith&#8221; is allowed to be re-issued to a different user at some point in the future, that is going to create problems.</p>

<p>An alternate solution would be to simply <strong>use better identifiers</strong>.  At USC, we had another user attribute called the &#8220;uscPVID&#8221; which we used instead of username.  This was itself an opaque identifier that effectively served as the primary key within the enterprise directory.  Even if all the other data for a user changed like their name and username, the uscPVID would remain the same.  The same kind of persistent key can be obtained for relying parties by creating a lookup table that maps the relying party&#8217;s public ID to some more persistent internal ID.  If and when a relying party changes their public ID, you simply modify, or add a new entry in your lookup table.</p>

<p>Finally, an identity provider could <strong>migrate from old to new identifiers</strong>, either with a one time update, or gradually.  For a one time update, the identity provider would generate the old and new identifier for a user or set of users, and provide that information to the relying part out of band.  The relying party would then be responsible for updating their database accordingly.  Alternately, the new and old mapping could be provided gradually at the time of user login by using attributes.  This was the technique used at USC for updating relying parties of changes to a different user attribute known as the USCID.  For reasons I won&#8217;t bother explaining here, this 10 digit ID could change for a user when certain events occurred.  To alert relying parties, we would include two attributes &#8212; the current USCID for the user, along with a list of &#8220;historical&#8221; USCIDs for that user.  Relying parties were then responsible for updating any records they had for one of the historical USCIDs to the current USCID of the user.</p>

<h2>Application to OpenID</h2>

<p>The above hashing method could be used with little or no modification to create directed identity URLs for OpenID users.  You could of course simply generate completely random IDs and store them in the database&#8230; that works too.  In my next post however, I&#8217;ll be talking about a new kind of OpenID service I&#8217;ve been doing a lot of thinking about, an OpenID proxy which works to protect the privacy of OpenIDs that don&#8217;t support directed identity themselves.  We&#8217;ll be using the above hashing algorithm, but doing some interesting things with the user identifier.</p>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2009/07/openid-directed-identity-identifier-select' rel='bookmark' title='Permanent Link: Directed Identity vs Identifier Select'>Directed Identity vs Identifier Select</a></li>
<li><a href='http://willnorris.com/2009/08/a-new-kind-of-openid-proxy' rel='bookmark' title='Permanent Link: A New Kind of OpenID Proxy'>A New Kind of OpenID Proxy</a></li>
<li><a href='http://willnorris.com/2007/03/openid-provider-wish-list' rel='bookmark' title='Permanent Link: OpenID provider wish-list'>OpenID provider wish-list</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2009/08/best-practices-with-directed-identity/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Why I&#8217;m going to Vidoop</title>
		<link>http://willnorris.com/2008/05/why-im-going-to-vidoop</link>
		<comments>http://willnorris.com/2008/05/why-im-going-to-vidoop#comments</comments>
		<pubDate>Thu, 15 May 2008 07:52:25 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[identity]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[diso]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[shibboleth]]></category>
		<category><![CDATA[usc]]></category>
		<category><![CDATA[vidoop]]></category>
		<category><![CDATA[wp-openid]]></category>

		<guid isPermaLink="false">http://willnorris.com/?p=226</guid>
		<description><![CDATA[So it&#8217;s not exactly news at this point, but it is indeed true that as of today I am now employed by Vidoop.  This has been a few months in the making, so I figured I&#8217;d explain a little of why and how we got to this point.

I&#8217;ve been working in the Identity Management [...]

<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2007/02/one-year-at-usc' rel='bookmark' title='Permanent Link: One year at USC'>One year at USC</a></li>
<li><a href='http://willnorris.com/2007/12/wp-openid-moving-to-diso' rel='bookmark' title='Permanent Link: wp-openid moving to DiSo'>wp-openid moving to DiSo</a></li>
<li><a href='http://willnorris.com/2010/01/going-to-google' rel='bookmark' title='Permanent Link: Going to Google'>Going to Google</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<p>So it&#8217;s <a href="http://blog.vidoop.com/archives/111">not</a> <a href="http://www.readwriteweb.com/archives/messina_norris_vidoop.php">exactly</a> <a href="http://factoryjoe.com/blog/2008/05/13/im-joining-vidoop-to-work-on-diso-full-time/">news</a> <a href="http://kveton.com/blog/2008/05/14/solutions-more-than-technology/">at</a> <a href="http://redmonk.net/archives/2008/05/14/distributed-social-networkers/">this</a> point, but it is indeed true that as of today I am now employed by Vidoop.  This has been a few months in the making, so I figured I&#8217;d explain a little of why and how we got to this point.</p>

<p>I&#8217;ve been working in the Identity Management space for a few years now.  I started getting involved with the <a href="http://shibboleth.internet2.edu/">Shibboleth</a> project while at the University of Memphis.  After a year and a half, I moved to California and took a job at USC working in their middleware group.  I&#8217;ve spent the last two years there helping to develop and manage various parts of the Identity Management cloud including the LDAP directories, meta-directory processes, and their Shibboleth environment.  In October 2006 I formally joined the core Shibboleth development team, focusing on the Shibboleth 2.0 Identity Provider.</p>

<p>Meanwhile, I have also been toying with OpenID for a couple of years.  In early 2007 or so, I sort of took over development of Alan Castonguay&#8217;s OpenID plugin for WordPress.  I started with a couple of new features, then worked to add support for the latest OpenID protocol, lots of code refactoring, etc.  I got to know characters like Chris Messina, Scott Kveton, and a host of others.  I continued making updates to the WordPress plugin as I had time, but it never felt like enough.  Don&#8217;t get me wrong, I certainly enjoyed the work I was doing at USC and with Shibboleth&#8230; I just would have liked to have had more time for everything else as well.  Every now and then Chris or Scott would prod me about going to work at Google or somewhere to spend more time on OpenID and related technologies, but I wasn&#8217;t ready to leave my work at USC.</p>

<p>Late last year, Chris Messina and Steve Ivy announced the DiSo Project, initially based on my updated wp-openid plugin.  Within the first week after it was announced, I sat down with Chris and Steve and we decided it would be best to officially move the wp-openid plugin under the DiSo umbrella to allow for tighter integration with the other planned work.  Then a lot happened this last February in the social networking space &#8212; Google <a href="http://google-code-updates.blogspot.com/2008/02/urls-are-people-too.html">announced</a> the Social Graph API and <a href="http://sgfoocamp08.pbwiki.com/FrontPage">SGFoo</a> really got people talking more about enriching the OpenID endpoint (<a href="http://kveton.com/blog/2008/02/04/sg-foocamp-08-wrap-up/">among other things</a>).  Things were beginning to move pretty fast, and I felt like if I didn&#8217;t jump in now then I&#8217;d end up watching all the great new developments from the sidelines.  I spent the next few months interviewing with a number of companies active in this space and made a couple of trips to San Francisco to talk with them in person.</p>

<p>In the end, a dinner conversation with <a href="http://www.vidoop.com/management.php">Luke Sontag</a> had me sold.  I was quite familiar with Vidoop and their OpenID provider, knew they had a great development team, but had always been a little skeptical of the company.  After Luke gave me a better picture of their overall vision and where technologies like DiSo fit into that picture, I knew that these guys really &#8220;get it&#8221;.  They understand the importance of what DiSo is trying to do, and more importantly they are willing to do their part in making it a reality.  I love Vidoop&#8217;s OpenID implementation and have been using it since before I took this job, but that&#8217;s not why I did.  I took the job because the team at Vidoop know their shit, they know the kinds of problems we&#8217;re up against, and they are ready to take a shot at developing some real solutions.  Well that and I really can&#8217;t wait to get started working with Chris a lot more. :)</p>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2007/02/one-year-at-usc' rel='bookmark' title='Permanent Link: One year at USC'>One year at USC</a></li>
<li><a href='http://willnorris.com/2007/12/wp-openid-moving-to-diso' rel='bookmark' title='Permanent Link: wp-openid moving to DiSo'>wp-openid moving to DiSo</a></li>
<li><a href='http://willnorris.com/2010/01/going-to-google' rel='bookmark' title='Permanent Link: Going to Google'>Going to Google</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2008/05/why-im-going-to-vidoop/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>New Beginnings</title>
		<link>http://willnorris.com/2008/04/new-beginnings</link>
		<comments>http://willnorris.com/2008/04/new-beginnings#comments</comments>
		<pubDate>Fri, 18 Apr 2008 16:07:33 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[personal]]></category>
		<category><![CDATA[job]]></category>
		<category><![CDATA[marriage]]></category>
		<category><![CDATA[sfo]]></category>
		<category><![CDATA[shibboleth]]></category>
		<category><![CDATA[usc]]></category>
		<category><![CDATA[wedding]]></category>

		<guid isPermaLink="false">http://willnorris.com/?p=224</guid>
		<description><![CDATA[I guess I never actually mentioned it here on my site, but I&#8217;m getting married in two weeks.  If you remember, I originally moved to California for Elisabeth a little over two years ago, and now we&#8217;re finally getting married.  We&#8217;re both definitely excited about it, but at least for the next week [...]

<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2008/06/wedding-photos' rel='bookmark' title='Permanent Link: Wedding Photos'>Wedding Photos</a></li>
<li><a href='http://willnorris.com/2007/02/one-year-at-usc' rel='bookmark' title='Permanent Link: One year at USC'>One year at USC</a></li>
<li><a href='http://willnorris.com/2005/07/looking-back-on-22' rel='bookmark' title='Permanent Link: Looking back on 22'>Looking back on 22</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<p>I guess I never actually mentioned it here on my site, but <a href="http://willnorris.com/wedding/">I&#8217;m getting married</a> in two weeks.  If you remember, I originally <a href="http://willnorris.com/2006/01/life-and-love-and-why">moved to California</a> for Elisabeth a little over two years ago, and now we&#8217;re finally getting married.  We&#8217;re both definitely excited about it, but at least for the next week and half we&#8217;re just stressed out trying to get everything ready.</p>

<p>Every marriage counseling book in the world would probably recommend otherwise, but I&#8217;m also taking a new job when we get back from the honeymoon.  I resigned my position at USC early last week, and my last day will be next Friday April 25th, 2008.  It is a bit bittersweet, as I really wish I would have had the time to wrap up more of the unfinished projects I&#8217;m leaving behind, but I trust that they are in good enough hands and will be well cared for.  If things go as planned, I will continue on as part of the core Shibboleth development team, which I feel is very important.  There are a few major additions to Shibboleth we&#8217;ve talked about adding, but simply haven&#8217;t had the time.  The primary attraction to the new job is quite simply the work I&#8217;ll be doing and who I&#8217;ll be doing it with &#8212; I&#8217;ll finally be able to really dig in to some of the projects that haven&#8217;t received the level of attention I would have liked to give.  Aside from that, I don&#8217;t think I&#8217;m ready to say too much else about the new job, only that it is in San Francisco and that we will be moving up there as soon as the wedding is over and we find a place.</p>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2008/06/wedding-photos' rel='bookmark' title='Permanent Link: Wedding Photos'>Wedding Photos</a></li>
<li><a href='http://willnorris.com/2007/02/one-year-at-usc' rel='bookmark' title='Permanent Link: One year at USC'>One year at USC</a></li>
<li><a href='http://willnorris.com/2005/07/looking-back-on-22' rel='bookmark' title='Permanent Link: Looking back on 22'>Looking back on 22</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2008/04/new-beginnings/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>try { reuse; } catch (Ex) { reinvent; }</title>
		<link>http://willnorris.com/2007/11/try-reuse-catch-ex-reinvent</link>
		<comments>http://willnorris.com/2007/11/try-reuse-catch-ex-reinvent#comments</comments>
		<pubDate>Tue, 06 Nov 2007 03:49:45 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[identity]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[hcard]]></category>
		<category><![CDATA[ldap]]></category>
		<category><![CDATA[microformats]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[openid-ax]]></category>
		<category><![CDATA[saml]]></category>
		<category><![CDATA[shibboleth]]></category>

		<guid isPermaLink="false">http://willnorris.com/2007/11/try-reuse-catch-ex-reinvent</guid>
		<description><![CDATA[Earlier today, I wrote about the limitations of hCard primarily in regards to private data.  After talking with Chris briefly and then reading Tantek&#8217;s thoughts on the topic, it clicked with me.  I wouldn&#8217;t normally make two posts so close together about such similar topics, but I realize now these really are two [...]

<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2007/10/openid-is-not-a-provisioning-engine' rel='bookmark' title='Permanent Link: OpenID is not a provisioning engine'>OpenID is not a provisioning engine</a></li>
<li><a href='http://willnorris.com/2007/11/hcard-is-not-a-provisioning-engine-for-private-data' rel='bookmark' title='Permanent Link: hCard is not a provisioning engine (for private data)'>hCard is not a provisioning engine (for private data)</a></li>
<li><a href='http://willnorris.com/2009/08/best-practices-with-directed-identity' rel='bookmark' title='Permanent Link: Best Practices with Directed Identity'>Best Practices with Directed Identity</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<p>Earlier today, I wrote about the <a href="http://willnorris.com/2007/11/hcard-is-not-a-provisioning-engine-for-private-data">limitations of hCard</a> primarily in regards to private data.  After talking with <a href="http://factoryjoe.com/blog/2007/11/01/hcard-for-openid-simple-registration-and-attribute-exchange/">Chris</a> briefly and then reading <a href="http://tantek.com/log/2007/11.html#d02t2318">Tantek&#8217;s thoughts</a> on the topic, it clicked with me.  I wouldn&#8217;t normally make two posts so close together about such similar topics, but I realize now these really are two different topics.  The concerns about hCard and privacy are very real and certainly worth consideration, but what Chris was really getting at was attribute naming.</p>

<p><span id="more-208"></span></p>

<h3>OpenID attributes</h3>

<p>The OpenID <a href="http://openid.net/specs/openid-simple-registration-extension-1_0.html">Simple Registration Extension</a> was designed, much like OpenID itself, to address a very specific use case &#8212; providing the most common data requested when registering at a new website (things like name, email, gender, etc).  It defines a fixed list of nine attributes that can be provided, and it works well for what it does, but it&#8217;s a bit rigid when one tries to do anything more with it.  Even before the final draft of the SREG extension had been published, work was already being done on a more flexible extension for <a href="http://openid.net/specs/openid-attribute-exchange-1_0-07.html">attribute exchange</a>.  This new extension defined only a mechanism for transferring attributes, but didn&#8217;t prescribe a fixed list of attributes.  But in order to be at all useful, two parties must be assured that they are both talking about the same attribute.  Therefore an attribute registry was established at <a href="http://www.axschema.org/">axschema.org</a> and a number of attributes (formatted as URLs) have <a href="http://www.axschema.org/types/">already been defined</a> which will likely be useful in common scenarios.</p>

<h3>Attributes in Higher Education</h3>

<p>Developed in the early 90s at the University of Michigan, LDAP quickly grew favor with higher education institutions to replace heavier-weight directory protocols.  A number of LDAP object classes were defined to provide attributes deemed useful in certain contexts, for example <a href="http://www.faqs.org/rfcs/rfc2798.html">rfc2798</a> defined <code>inetOrgPerson</code> which addressed the needs of &#8220;Internet and Intranet directory service deployments&#8221;.  Higher Education had its own unique needs, so in 2001 Internet2 published the first version of the <a href="http://www.educause.edu/eduperson/">eduPerson Object Class</a>.  If (and only if) institutions required additional attributes beyond those provided by some already published object class, it was common practice to define a local object class to house those attributes.</p>

<p>Within a few years, the SAML specification was published and <a href="http://shibboleth.internet2.edu/">Shibboleth</a> began finding its way onto many college campuses.  Though not required by SAML, Shibboleth recommended the use of URIs for SAML attribute names, and subsequently established a <a href="http://www.google.com/search?q=cache:http://middleware.internet2.edu/dir/docs/internet2-mace-dir-saml-attributes-200604.pdf">collection of URN values</a> to represent common LDAP attributes, including those defined in the eduPerson object class.  As before, if campuses needed to include additional attributes in a SAML assertion, they were defined within a local namespace.  Today, it is very common to see a mix of attributes at USC including those defined by Internet2:</p>

<ul>
<li><code>urn:mace:dir:attribute-def:displayName</code></li>
<li><code>urn:mace:dir:attribute-def:eduPersonAffiliation</code></li>
</ul>

<p>as well as those we have defined locally at USC:</p>

<ul>
<li><code>urn:mace:usc.edu:gds:attribute-def:uscUSCID</code></li>
<li><code>urn:mace:usc.edu:gds:attribute-def:uscStudentDegreeProgram</code></li>
</ul>

<h3>Applying Precedence</h3>

<p>No one is pretending that the fixed set of attributes defined in <a href="http://www.faqs.org/rfcs/rfc2426.html">rfc2426</a> is the definitive list of attributes that could possibly be useful in OpenID, no more than eduPerson was the exhaustive list of attributes for every university that used it.  All that is being questioned is why did Attribute Exchange redefine all that was already established in vCard?  I would strongly support Tantek&#8217;s third proposal of hosting the official hCard XMDP profile at <code>http://microformats.org/profile/hcard</code>, so that AX can leverage the hCard specification while maintaining URL based attribute names.  And given that it appears as though <a href="http://willnorris.com/openid-support">no one is currently supporting AX</a>, <strong>now</strong> is the time to make this change.</p>

<p>(For the non-technical, the title roughly reads &#8220;First try to reuse.  Only if that doesn&#8217;t work, then reinvent.&#8221;)</p>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2007/10/openid-is-not-a-provisioning-engine' rel='bookmark' title='Permanent Link: OpenID is not a provisioning engine'>OpenID is not a provisioning engine</a></li>
<li><a href='http://willnorris.com/2007/11/hcard-is-not-a-provisioning-engine-for-private-data' rel='bookmark' title='Permanent Link: hCard is not a provisioning engine (for private data)'>hCard is not a provisioning engine (for private data)</a></li>
<li><a href='http://willnorris.com/2009/08/best-practices-with-directed-identity' rel='bookmark' title='Permanent Link: Best Practices with Directed Identity'>Best Practices with Directed Identity</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2007/11/try-reuse-catch-ex-reinvent/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>hCard is not a provisioning engine (for private data)</title>
		<link>http://willnorris.com/2007/11/hcard-is-not-a-provisioning-engine-for-private-data</link>
		<comments>http://willnorris.com/2007/11/hcard-is-not-a-provisioning-engine-for-private-data#comments</comments>
		<pubDate>Mon, 05 Nov 2007 23:29:53 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[identity]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[hcard]]></category>
		<category><![CDATA[microformats]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[openid-ax]]></category>
		<category><![CDATA[saml]]></category>
		<category><![CDATA[shibboleth]]></category>

		<guid isPermaLink="false">http://willnorris.com/2007/11/hcard-is-not-a-provisioning-engine-for-private-data</guid>
		<description><![CDATA[Last week I wrote about how hCard is much more appropriate than OpenID for the provisioning use-case and Chris continued that discussion, questioning why we need SREG and Attribute Exchange when hCard works just fine.


  So the question is, when OpenID is clearly a player in the future and part of that promise is [...]

<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2007/10/openid-is-not-a-provisioning-engine' rel='bookmark' title='Permanent Link: OpenID is not a provisioning engine'>OpenID is not a provisioning engine</a></li>
<li><a href='http://willnorris.com/2007/11/try-reuse-catch-ex-reinvent' rel='bookmark' title='Permanent Link: try { reuse; } catch (Ex) { reinvent; }'>try { reuse; } catch (Ex) { reinvent; }</a></li>
<li><a href='http://willnorris.com/2007/03/openid-provider-wish-list' rel='bookmark' title='Permanent Link: OpenID provider wish-list'>OpenID provider wish-list</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<p>Last week I wrote about how hCard is much more appropriate than OpenID for <a href="http://willnorris.com/2007/10/openid-is-not-a-provisioning-engine">the provisioning use-case</a> and Chris <a href="http://factoryjoe.com/blog/2007/11/01/hcard-for-openid-simple-registration-and-attribute-exchange/">continued that discussion</a>, questioning why we need SREG and Attribute Exchange when hCard works just fine.</p>

<blockquote>
  <p>So the question is, when OpenID is clearly a player in the future and part of that promise is about 
  making things easier, more consistent and more citizen-centric, why would we go and introduce a <strong>whole 
  new format</strong> for representing person-detail-data when a perfectly good one already exists and is so 
  widely supported?</p>
</blockquote>

<p>While I certainly agree with Chris that hCard has a role to play in the new world of online identity, I don&#8217;t want SREG or AX to be dismissed too quickly.  I don&#8217;t believe he was suggesting that hCard would replace SREG/AX in all use cases, but I want to labor this point just a little bit so that others are not confused.</p>

<p><span id="more-207"></span></p>

<p>There is one huge benefit to SREG and AX that hCard doesn&#8217;t (and by it&#8217;s nature, can&#8217;t) address&#8230; releasing different attributes to different relying parties.  This can take a number of forms.  The one most commonly supported in OpenID providers today is the idea of personas - a complete set of attribute values that reflect your online identity within a particular context.  You may have a &#8220;work&#8221; persona that includes your formal name, work email address and website, etc.  Separately, you may have a &#8220;personal&#8221; persona that has some informal nickname along with a personal email address, website. etc.  Separate still, you may have an &#8220;anonymous&#8221; persona that includes little (or fabricated) data about yourself.  Depending on which relying party you are authenticating to, you may use a particular persona.</p>

<p>Varying this slightly, one can imagine a use case that will be become increasingly important as OpenID continues to expand.  hCard is suitable for public attributes I want to post for the world to see, but what about not-so-public data?  It will likely be some time before we start transferring credit card numbers over OpenID+AX, but I have no doubt it will happen eventually (as nervous as that makes even me).  But even before then, I can imagine a host of data that I may need or want to provide to a relying party, but do not want to publish in my public hCard.  As I included in my <a href="http://willnorris.com/2007/03/openid-provider-wish-list">OpenID provider wish-list</a>, OpenID providers will need to provide the tools to manage the policies controlling this release of data, a feature that has the potential to really differentiate one provider from the rest of the pack.  This fine-grained level of control has always been a core requirement for the <a href="http://shibboleth.internet2.edu/">Shibboleth</a> SAML Identity provider, and I would argue that the (currently beta) Shibboleth 2.0 IdP has one of the most powerful and flexible (and admittedly, verbose) <a href="https://spaces.internet2.edu/display/SHIB2/AFPAttributeFilterPolicy">filtering engines</a> of its kind anywhere.</p>

<p>So there are really two issues at play in Chris&#8217;s question, that of the data format and separately, the mechanism for conveying that data.  I haven&#8217;t really addressed the issue of the data format, because I agree with Chris in principal at least.  His <a href="http://microformats.org/wiki/attribute-exchange">comparison table</a> of attribute names shows a very clear overlap between the different methods, and perhaps it would be useful to work to consolidate some of that.  But the mechanisms for making that data available address different, and equally valid, use cases and each play a role in making all of this stuff work.</p>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2007/10/openid-is-not-a-provisioning-engine' rel='bookmark' title='Permanent Link: OpenID is not a provisioning engine'>OpenID is not a provisioning engine</a></li>
<li><a href='http://willnorris.com/2007/11/try-reuse-catch-ex-reinvent' rel='bookmark' title='Permanent Link: try { reuse; } catch (Ex) { reinvent; }'>try { reuse; } catch (Ex) { reinvent; }</a></li>
<li><a href='http://willnorris.com/2007/03/openid-provider-wish-list' rel='bookmark' title='Permanent Link: OpenID provider wish-list'>OpenID provider wish-list</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2007/11/hcard-is-not-a-provisioning-engine-for-private-data/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>OpenID is not a provisioning engine</title>
		<link>http://willnorris.com/2007/10/openid-is-not-a-provisioning-engine</link>
		<comments>http://willnorris.com/2007/10/openid-is-not-a-provisioning-engine#comments</comments>
		<pubDate>Tue, 30 Oct 2007 08:11:46 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[identity]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[hcard]]></category>
		<category><![CDATA[ldap]]></category>
		<category><![CDATA[microformats]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[openid-ax]]></category>
		<category><![CDATA[provisioning]]></category>
		<category><![CDATA[saml]]></category>
		<category><![CDATA[shibboleth]]></category>

		<guid isPermaLink="false">http://willnorris.com/2007/10/openid-is-not-a-provisioning-engine</guid>
		<description><![CDATA[In talking about the future possibilities of OpenID 2.0 and the Attribute Exchange extension, James Henstridge mentions,


  Imagine being able to update your shipping address in one place when you 
  move house and having all the online retailers you use receive the updated 
  address immediately. Or changing your email address [...]

<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2007/11/hcard-is-not-a-provisioning-engine-for-private-data' rel='bookmark' title='Permanent Link: hCard is not a provisioning engine (for private data)'>hCard is not a provisioning engine (for private data)</a></li>
<li><a href='http://willnorris.com/2007/11/try-reuse-catch-ex-reinvent' rel='bookmark' title='Permanent Link: try { reuse; } catch (Ex) { reinvent; }'>try { reuse; } catch (Ex) { reinvent; }</a></li>
<li><a href='http://willnorris.com/2009/08/best-practices-with-directed-identity' rel='bookmark' title='Permanent Link: Best Practices with Directed Identity'>Best Practices with Directed Identity</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<p>In talking about the future possibilities of OpenID 2.0 and the <a href="http://openid.net/specs/openid-attribute-exchange-1_0-07.html">Attribute Exchange</a> extension, <a href="http://blogs.gnome.org/jamesh/2007/10/23/openid-20/">James Henstridge</a> mentions,</p>

<blockquote>
  <p>Imagine being able to update your shipping address in one place when you 
  move house and having all the online retailers you use receive the updated 
  address immediately. Or changing your email address and having all the 
  bugzilla instances you use pick up the new address instantly (perhaps 
  requiring you to verify the new address first, of course).</p>
</blockquote>

<p>While I agree this kind of experience would be very neat, it is not a use case for OpenID nor the Attribute Exchange extension.<span id="more-206"></span>  I am not surprised to hear someone say this, as this is a common point of confusion here at USC in regards to <a href="http://shibboleth.internet2.edu/">Shibboleth</a>.  When it comes to attribute delivery, both OpenID and SAML are primarily designed to provide data <em>at the time of login</em> <sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>.  So this means that if a user never logs in to your service, you never get any data about them.  And if a user&#8217;s data changes since their last login, you don&#8217;t find out about until they <em>next</em> login, since that is the only time attribute delivery occurs.  It is also important to note that you are typically only getting data about the user that is logging in, no one else.  You can&#8217;t treat an OpenID provider as a lookup service to get data about some other user.</p>

<p>So how does a relying party update their data without waiting on the user to login again?  One option is to have the data pushed to each service using some kind of messaging hub.  There is a whole market for enterprise messaging complete with its own set of acronyms like <a href="http://en.wikipedia.org/wiki/Enterprise_service_bus">ESB</a>, <a href="http://en.wikipedia.org/wiki/Enterprise_messaging_system">EMS</a>, <a href="http://en.wikipedia.org/wiki/Enterprise_application_integration">EAI</a>, and many many more.  I&#8217;m particularly interested in a project developed by a colleague of mine in Sweden called <a href="http://devel.it.su.se/pub/jsp/polopoly.jsp?d=1227">JEvent</a>, which uses the XMPP <a href="http://www.xmpp.org/extensions/xep-0060.html">Publish-Subscribe</a> protocol to deliver these types of messages using a standard XMPP server in the middle.  Your Jabber messaging window becomes your console. :)</p>

<p>The other method of getting at user data is for each relying party to pull the data.  This is the model we use at USC, where that mechanism for pulling data is LDAP.  A number of services on campus use LDAP to address both use cases mentioned above &#8212; refreshing data about users, as well as looking up data about someone other than the user who logged in.  So what&#8217;s the equivalent in the decentralized OpenID world?  Well honestly there isn&#8217;t anything just yet but we have a good foundation.  Thanks to <a href="http://microformats.org/">microformats</a> like <a href="http://microformats.org/wiki/hcard">hCard</a>, you can publish your data in a standard, machine-parsable format that your online retailers or bugzilla instances could watch periodically.  When you update your hCard on your homepage they can respond in kind, perhaps by immediately updating their databases or sending you a confirmation email of the change.  Right now all of this data is decentralized, published on personal blogs and webpages.  I don&#8217;t argue that this data should certainly be under individual control, but it puts an awful large burden on the individual service providers to do all that spidering.  I don&#8217;t know what the answer is, but I&#8217;ve been thinking about an hCard crawler with an LDAP front-end as a simple place to start.  Configure Apple AddressBook or Outlook to use LDAP, and you&#8217;re off and running.</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>SAML is actually a little more flexible here, but it&#8217;s not the common use case&#160;<a href="#fnref:1" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2007/11/hcard-is-not-a-provisioning-engine-for-private-data' rel='bookmark' title='Permanent Link: hCard is not a provisioning engine (for private data)'>hCard is not a provisioning engine (for private data)</a></li>
<li><a href='http://willnorris.com/2007/11/try-reuse-catch-ex-reinvent' rel='bookmark' title='Permanent Link: try { reuse; } catch (Ex) { reinvent; }'>try { reuse; } catch (Ex) { reinvent; }</a></li>
<li><a href='http://willnorris.com/2009/08/best-practices-with-directed-identity' rel='bookmark' title='Permanent Link: Best Practices with Directed Identity'>Best Practices with Directed Identity</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2007/10/openid-is-not-a-provisioning-engine/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Shibboleth definition</title>
		<link>http://willnorris.com/2007/04/shibboleth-definition</link>
		<comments>http://willnorris.com/2007/04/shibboleth-definition#comments</comments>
		<pubDate>Thu, 19 Apr 2007 07:17:47 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[identity]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[shibboleth]]></category>

		<guid isPermaLink="false">http://willnorris.com/2007/04/shibboleth-definition</guid>
		<description><![CDATA[Perhaps the best definition of Shibboleth I&#8217;ve ever seen:


  Shibboleth loosely translated means, &#8220;Who the fuck are you?&#8221;
  - Dead Library



Possibly related posts:Shibboleth 1.3 released
Java OpenID Library - Target Audience
One year at USC


<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2005/07/shibboleth-13-released' rel='bookmark' title='Permanent Link: Shibboleth 1.3 released'>Shibboleth 1.3 released</a></li>
<li><a href='http://willnorris.com/2009/12/java-openid-library-target-audience' rel='bookmark' title='Permanent Link: Java OpenID Library - Target Audience'>Java OpenID Library - Target Audience</a></li>
<li><a href='http://willnorris.com/2007/02/one-year-at-usc' rel='bookmark' title='Permanent Link: One year at USC'>One year at USC</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<p>Perhaps the best definition of Shibboleth I&#8217;ve ever seen:</p>

<blockquote>
  <p>Shibboleth loosely translated means, &#8220;Who the fuck are you?&#8221;<br />
  - <a href="http://vkwn.com/deadlibrary/2007/03/27/goodbye-athens-hello-shibboleth-and-federated-access-management/">Dead Library</a></p>
</blockquote>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2005/07/shibboleth-13-released' rel='bookmark' title='Permanent Link: Shibboleth 1.3 released'>Shibboleth 1.3 released</a></li>
<li><a href='http://willnorris.com/2009/12/java-openid-library-target-audience' rel='bookmark' title='Permanent Link: Java OpenID Library - Target Audience'>Java OpenID Library - Target Audience</a></li>
<li><a href='http://willnorris.com/2007/02/one-year-at-usc' rel='bookmark' title='Permanent Link: One year at USC'>One year at USC</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2007/04/shibboleth-definition/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>OpenID provider wish-list</title>
		<link>http://willnorris.com/2007/03/openid-provider-wish-list</link>
		<comments>http://willnorris.com/2007/03/openid-provider-wish-list#comments</comments>
		<pubDate>Thu, 08 Mar 2007 09:35:04 +0000</pubDate>
		<dc:creator>Will Norris</dc:creator>
				<category><![CDATA[identity]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[myopenid]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[prooveme]]></category>
		<category><![CDATA[shibboleth]]></category>

		<guid isPermaLink="false">http://willnorris.com/2007/03/openid-provider-wish-list</guid>
		<description><![CDATA[A week or so ago, Nic Ferrier of prooveme contacted me about a previous post I made that referenced prooveme.com in regards to strong authentication.  He ended the email,


  We&#8217;d like to be your provider of choice - so do tell us what you want to see.


I had been meaning to post a [...]

<div class="related-posts">
Possibly related posts:<ul><li><a href='http://willnorris.com/2007/11/hcard-is-not-a-provisioning-engine-for-private-data' rel='bookmark' title='Permanent Link: hCard is not a provisioning engine (for private data)'>hCard is not a provisioning engine (for private data)</a></li>
<li><a href='http://willnorris.com/2007/02/strong-authentication-and-emailing-passwords' rel='bookmark' title='Permanent Link: strong authentication and emailing passwords'>strong authentication and emailing passwords</a></li>
<li><a href='http://willnorris.com/2007/10/openid-is-not-a-provisioning-engine' rel='bookmark' title='Permanent Link: OpenID is not a provisioning engine'>OpenID is not a provisioning engine</a></li>
</ul></div>]]></description>
			<content:encoded><![CDATA[<p>A week or so ago, Nic Ferrier of <a href="http://prooveme.com">prooveme</a> contacted me about a <a href="http://willnorris.com/2007/02/strong-authentication-and-emailing-passwords">previous post</a> I made that referenced prooveme.com in regards to strong authentication.  He ended the email,</p>

<blockquote>
  <p><em>We&#8217;d</em> like to be your provider of choice - so do tell us what you want to see.</p>
</blockquote>

<p>I had been meaning to post a reply to this for several days, but now with Martin Atkins&#8217;s <a href="http://openid.net/wiki/index.php/Relying_Party_Best_Practices">Relying Party Best Practices</a>, it seems like an ideal time to discuss this.  Here is a short list of items I came up with that I&#8217;d like to see in an OpenID provider, roughly in priority order.  A number of them are already addressed by one or more existing providers, while several are not.</p>

<ul>
<li><p><strong>SSL</strong> &#8212; not having SSL is an immediate deal breaker.  If my password or my personal information is going over the wire, it sure as hell better be over an encrypted connection.</p></li>
<li><p><strong>Strong Authentication</strong> &#8212; this was the primary topic of the aforementioned post, and more details can be found there.  The main point, however, is that I&#8217;d like some kind of stronger authentication mechanism than just a single username and password.  As more OpenID enabled services come online, the more important it will become to have a stronger mechanism to identify the user.  This might be in the form of an client SSL certificate like <a href="http://prooveme.com">prooveme</a> and <a href="http://certifi.ca">certifi.ca</a> use, or a one-time-use password like <a href="http://iamdentity.com">iamdentity</a>.</p></li>
<li><p><strong>Auditing</strong> &#8212; It looks like a number of providers allow you to see and modify the list of all the relying parties you trust, and while that&#8217;s a good start, this could (and for some use cases, should) be expanded much beyond that.  I&#8217;d like to see a log of every time I authenticated to a particular relying party, and perhaps some additional information about that transaction such as IP address.  This could potentially help identify if and when my account has been compromised.  When attributes are released via simple-reg I want to see that, and it might also be useful to know exactly what values were released during a given transaction.  I may have updated an attribute a number of times since it was released to that relying party months ago, and I might like to know what values were sent to them.</p></li>
<li><p><strong>Real attribute release policies</strong> &#8212; Perhaps I&#8217;m just spoiled from working on <a href="http://shibboleth.internet2.edu">Shibboleth</a> for several years, but I would really like fine grained control over what attributes are delivered to a given relying party.  MyOpenID&#8217;s &#8220;persona&#8221; feature definitely comes pretty close on this, but I believe it is still an &#8220;all or nothing&#8221; choice &#8212; I can&#8217;t approve the release of only a subset of the attributes an RP requested.</p></li>
<li><p><strong>Modify attribute value for the current transaction</strong> &#8212; This somewhat carries over from the previous item.  MyOpenID has the ability to edit your persona just before you send it to the relying party (although this is a bit broken, because it completely breaks the OpenID flow if you do so).  In addition to making permanent modifications to a persona, I&#8217;d like to be able to modify the values that are released for the given transaction only.  For example, I may want to use my main persona for this relying party, but just change my email address to something different.</p></li>
<li><p><strong>Identity Linking</strong> &#8212; This is certainly in the running for being the latest &#8220;holy grail&#8221; of OpenID&#8230; the ability to link multiple OpenIDs in such a way that relying parties understand that they are equivalent.  I&#8217;m not even sure if the provider is the right party to address this problem (I imagine it will require work on both sides) but if someone is able to come up with a compelling solution, that would be very attractive.</p></li>
</ul>

<p>So there&#8217;s a few things I was able to think of in a short amount of time, but I&#8217;m sure I overlooked a bunch.  I&#8217;m curious to know what kind of features others would like to see in an OpenID provider.  Don&#8217;t limit yourself just to what you think is realistic or easy to implement in the short term&#8230; think bigger than that, this is a wish-list after all.</p>


<div class="related-posts"><p>Possibly related posts:</p><ul><li><a href='http://willnorris.com/2007/11/hcard-is-not-a-provisioning-engine-for-private-data' rel='bookmark' title='Permanent Link: hCard is not a provisioning engine (for private data)'>hCard is not a provisioning engine (for private data)</a></li>
<li><a href='http://willnorris.com/2007/02/strong-authentication-and-emailing-passwords' rel='bookmark' title='Permanent Link: strong authentication and emailing passwords'>strong authentication and emailing passwords</a></li>
<li><a href='http://willnorris.com/2007/10/openid-is-not-a-provisioning-engine' rel='bookmark' title='Permanent Link: OpenID is not a provisioning engine'>OpenID is not a provisioning engine</a></li>
</ul></div>]]></content:encoded>
			<wfw:commentRss>http://willnorris.com/2007/03/openid-provider-wish-list/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license>
	</item>
	</channel>
</rss>
