Sunday, June 26, 2005

Tuesday, June 21, 2005

SOAP Client Widget for Tiger

Thought I'd share my little experiment with Dashboard Widgets

It's a little AJAX Soap Client - provide the payload for the SOAP body, and it will post a message with wsa:Action and wsse:UserNameToken. The response is displayed back.

Milo's favorite barksdale-ism

Sunday, June 19, 2005

Here's what ended up on the wire

This was sent to my service. As, you can see that InfoCard has automatically created a SAML 1.1 assertion bearing the email address provided in the selected InfoCard. What's not clear to me is what's going on with the action - its' using a wa-addressing action that is not defined in ws-trust...hmm. Anyone? I wish the body weren't mysteriously encryted....

[Update: Mark Wahl passed this along

"When requesting and returning security context tokens the following Action URIs are used
http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT"
in WS-SecureConversation Feb '05.

Thanks Mark! ]


POST /simpleservice HTTP/1.1 Content-Type: application/soap+xml; charset="utf-8"; action="http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT"
Host: 192.168.9.11
Content-Length: 12838
Expect: 100-continue
Connection: Keep-Alive

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<a:Action u:Id="_1" s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT</a:Action>
<a:MessageID u:Id="_2">uuid:674467cc-10bd-4bd4-a4b6-fba565035d01;id=0</a:MessageID>
<a:To u:Id="_3" s:mustUnderstand="1">http://192.168.9.10:8080/simpleservice</a:To>
<dsig:X509Certificate xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">..../BjHqg==</dsig:X509Certificate>
<a:ReplyTo u:Id="_4">
<a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
</a:ReplyTo>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2005-06-20T00:44:36.734Z</u:Created>
<u:Expires>2005-06-21T00:44:36.734Z</u:Expires>
</u:Timestamp>
<e:EncryptedKey Id="uuid-dfeed4a3-da17-4699-80aa-dad0cccc082e-1" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<o:SecurityTokenReference>
<o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/2004/xx/oasis-2004xx-wss-x509-token-profile-1.1#X509ThumbprintSHA1">nNpk/FqUmDNX8fvv3bk9BVjY0eQ=</o:KeyIdentifier>
</o:SecurityTokenReference>
</KeyInfo>
<e:CipherData>
<e:CipherValue>GlV7KHIY0thaICqbatPYLaSRO4dyXxsR698bm9Po88K3iQpF1TvTC4HPp415eobwvUy7mLpM8XfOKEvfZ3fk0P4FjyXhtxQOnN35D7rCxVrnIu5zZqlNev9HqeqrUW05ocYgTGjD0RIV4XdRoScPiZU96EkzIfc6QsIFhGqo6RQ=</e:CipherValue>
</e:CipherData>
</e:EncryptedKey>
<c:DerivedKeyToken u:Id="_6" xmlns:c="http://schemas.xmlsoap.org/ws/2005/02/sc">
<o:SecurityTokenReference>
<o:Reference URI="#uuid-dfeed4a3-da17-4699-80aa-dad0cccc082e-1"/>
</o:SecurityTokenReference>
<c:Generation>0</c:Generation>
<c:Length>32</c:Length>
<c:Nonce>z3cSc/jtJ+UCF5CEQ8xsLg==</c:Nonce>
</c:DerivedKeyToken>
<saml:Assertion MajorVersion="1" MinorVersion="1" AssertionId="uuid-30365992-d9e4-46ad-9443-41b1aa1cc917" Issuer="http://schemas.xmlsoap.org/ws/2004/10/identity/issuer#self" IssueInstant="2005-06-20T00:44:35.718Z" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">
<saml:Conditions x:Id="1" NotBefore="2005-06-20T00:44:35.500Z" NotOnOrAfter="2005-06-20T00:54:35.500Z" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:x="http://schemas.microsoft.com/2003/10/Serialization/"/>
<saml:AttributeStatement x:Id="1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:x="http://schemas.microsoft.com/2003/10/Serialization/">
<saml:Subject x:Id="1">
<saml:NameIdentifier x:Id="1" Format="http://schemas.xmlsoap.org/ws/2004/10/identity#KeyThumbprint">9TGi5d7p2VFFnGtOZ5bmUwbpOJI=</saml:NameIdentifier>
<saml:SubjectConfirmation x:Id="1">
<saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:holder-of-key</saml:ConfirmationMethod>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<KeyValue>
<RSAKeyValue>
<Modulus>znzfPeulynSTfQRdMtkW3CTzR3G2T3l4YqI6Csdfq4huIEySzeCd1oEZ2aUtG/WjD1ZvgcNkaS8V6JuyU2+XGArNP/szM/KMIYDWa0vSkr1WpM+HUOK58fZXDQWTEaKzWJePMfOjUQefcg3CzK1uj1jM4pAVl6Hpv4862uIdzkWQ5SYV9mKu862Sc5RqF74KggMU3N9BzjPVWBrHzFIvJIQPsUWWRhb57N5qw2GzjPBDxK3ACKdkT/MA08Lnr4hSR/f827Zv363xN1BRinqcrfJE0GVr6/LL11qvZqaKEgd0NRnyKn+IR8VJbtpGMDcR03nZhkHFP87esFOD63zUIQ==</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Attribute x:Id="1" AttributeName="http://schemas.microsoft.com/ws/2004/10/identity#E-Mail-Address" AttributeNamespace="http://schemas.microsoft.com/ws/2004/10/identity">
<saml:AttributeValue>cmort@sxip.com</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#uuid-30365992-d9e4-46ad-9443-41b1aa1cc917">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>6EgVjHzVJvq5p8wA9CmRAa4428I=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>dHIsclXyt4S6/b485/Lw6t/0kAsJX3ctbJAtLZdSKoXiltOKLlOpnwrMESGDv6bwm3SjiadyF56MY0uWg8gqm65y8eO1o269CgQP4YB98LosaBnwzRXx63lzIp44rH6JcaOE0Cqq34P3cf5SxWC3BNaJpLfUbqrTw8wfHKIOxmc4bAaOMLMCV2QScbJQQYt1cE9b/mAtujl1cNzmGuDWVg2XyzwtE6HiPG8KvsgThDnz/ItzU2J9jfWBO7qXNDTM+EJt7LDn26HfixgxHDUm4W+wwxfhLGlER/KcNDWESOezBBd40diKpwIEALjZ/tAgLoGZPmnskFoaSLiDeeHTRQ==</SignatureValue>
<KeyInfo>
<KeyValue>
<RSAKeyValue>
<Modulus>znzfPeulynSTfQRdMtkW3CTzR3G2T3l4YqI6Csdfq4huIEySzeCd1oEZ2aUtG/WjD1ZvgcNkaS8V6JuyU2+XGArNP/szM/KMIYDWa0vSkr1WpM+HUOK58fZXDQWTEaKzWJePMfOjUQefcg3CzK1uj1jM4pAVl6Hpv4862uIdzkWQ5SYV9mKu862Sc5RqF74KggMU3N9BzjPVWBrHzFIvJIQPsUWWRhb57N5qw2GzjPBDxK3ACKdkT/MA08Lnr4hSR/f827Zv363xN1BRinqcrfJE0GVr6/LL11qvZqaKEgd0NRnyKn+IR8VJbtpGMDcR03nZhkHFP87esFOD63zUIQ==</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</Signature>
</saml:Assertion>
<e:ReferenceList xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:DataReference URI="#_7"/>
</e:ReferenceList>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#_0">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>t4R8JHI9sfYljoocDZ69/1HoAJU=</DigestValue>
</Reference>
<Reference URI="#_1">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>Q25uUOzeV9Aduvtw9eG9xMMNHrI=</DigestValue>
</Reference>
<Reference URI="#_2">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>f4UZdzH8TQGemsO2i2E+jIa6XDo=</DigestValue>
</Reference>
<Reference URI="#_3">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>QFhRuh49ZnX8S4z8iKi3diz7UDE=</DigestValue>
</Reference>
<Reference URI="#_4">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>zaBQWq9U/zdzkimMsCHucawY8qc=</DigestValue>
</Reference>
<Reference URI="#_5">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>6am03LAQSO20LZsE07ikNHHAazo=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>ZFL4QT1wu4N58VamcSyL4cJxEj3cKBCWEwNR4P06FlLKiCseyVp2SWGe1qciQCUdhZd5zQMcuUTXxlod9uN3HUPQdHZSGvvM2wTLsDnBYL7KQXgO+VHOmupGWIhI+aZiIPq1+IXv9hi5qqFb9hQ6/xB9i0iO5KZFe3bqjt67QrZDgtsFqYLT+GVkdq+4dKf+HTXsXSylm6eS5ce6gpCalTu+6XTB/8eG/kRLxFUXci4CTyipl/NLTqrFmmiln/dzPjeGrskjf2WZdmg8oXw+of46mb04fpWrE3vUqX1lfA7kdCFL3gP0bEiRgiHXOa9PhaQdOt/nt0mzfq3YHwc85w==</SignatureValue>
<KeyInfo>
<o:SecurityTokenReference>
<o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.0#SAMLAssertionID">uuid-30365992-d9e4-46ad-9443-41b1aa1cc917</o:KeyIdentifier>
</o:SecurityTokenReference>
</KeyInfo>
</Signature>
</o:Security>
</s:Header>
<s:Body u:Id="_5">
<e:EncryptedData Id="_7" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<o:SecurityTokenReference xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:Reference URI="#_6"/>
</o:SecurityTokenReference>
</KeyInfo>
<e:CipherData>
<e:CipherValue>lR2D1YctHtOdkC0bNrfP4BrpIOJkG5GxWVKm+LzkY7+1RKxhpL5IC1Z10ON8Vsg9+B7a7/....qRneyxtQ==</e:CipherValue>
</e:CipherData>
</e:EncryptedData>
</s:Body></s:Envelope>

Invoking InfoCard

With all that out of the way, I finally can invoke my client, and get into the InfoCard interface, as well as take a look at the resulting message enrichement

When I invoked the client, the first thing it does is validate the Identity of the service using the cert in the addessPropeties. Assuming validity, the InfoCard UI is invoked. The first thing you seen is presentation of the relying party, and potentially their terms of service, as well as prompt to either agree to their terms, or cancel the operation. I wish I had a screen shot, but there doesn't seem to be a simple means to remove a relying party from your trust list, or change its settings. I expect this will show up in future versions.

Once I accepted the terms, I'm prompted to select an InfoCard. This shows the UI for infocard actually being invoked:


Click for a larger version


A few things to notice here

1) They track which card I've previously presented, and when I did it
2) They track what the relying party already knows about me

From here, I can choose a card to submit. This talks to a local STS in the current beta, and generates a SAML assertion, which is used to enrich the SOAP call...

Now the App.config

InfoCard ends up getting invoked (at least in the Indigo use cases) via a custom binding in the services configuration file (app.config or web.config depending on selfhosting or was/iis hosted services)

The config file has 3 main sections required for InfoCard usage. The first is a custom binding. The binding section basically describes the protocol indigo will use to expose or talk to services in a declarative fasion. It ships with a number of default bindings for WS-I basic profile interop, WS-*, as well as some MSFT proprietary binary optimizations. You do have the ability to define a custom binding which gives you granular control over protocol. In order to use InfoCard, you seem to need to use a custom binding. Here is an example:


<bindings>
<customBinding>
<!-- Define custom binding for InfoCard. -->
<binding configurationName="InfoCardBinding">
<security authenticationMode="IssuedTokenForCertificate" contextMode="Session">
<federationParameters>
<tokenRequestParameters>
<xmlElement>
<wst:TokenType xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:wsid="http://schemas.xmlsoap.org/ws/2004/10/identity" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">urn:oasis:names:tc:SAML:1.0:assertion</wst:TokenType>
</xmlElement>
<xmlElement>
<wst:Claims xmlns:wsid="http://schemas.xmlsoap.org/ws/2004/10/identity" xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust">
<wsid:Claim wsid:URI="http://schemas.microsoft.com/ws/2004/10/identity#E-Mail-Address"/>
</wst:Claims>
</xmlElement>
</tokenRequestParameters>
</federationParameters>
</security>
<httpTransport/>
</binding>
customBinding>
</bindings>


This basically says that the authentication mode is IssuedTokenForCertificate which I believe indicates "Use InfoCard" It then designates the parameters which will be passed into the WS-Trust RST - in this case stating that it wants a SAML assertion with email address attribute assertion

Next, we need special behavior section which is referenced from the endpoint configuration. This indicates how to find the local certificate to exchange for the SAML assertion. This required importing the certificate into my local trusted store:


<behavior configurationName="TrustedCredentials" returnUnknownExceptionsAsFaults="true">
<channelSecurityCredentials>
<serviceX509Certificate findValue="Fabrikam" x509FindType="FindBySubjectName" storeLocation="CurrentUser" storeName="TrustedPeople" />
</channelSecurityCredentials>
</behavior>


It's not yet clear what other credential types can be used - there seem to be many options in the core Indigo APIs, but the authenticationMode of IssuedTokenForCertificate has me a bit concerned others aren't yet supported...

Finally, a addressProperties section is required:


<addressProperties identityType="Dns" identityData="Fabrikam">
<endpointHeaders>
<dsig:X509Certificate xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">MIIDwzCCAqu....==</dsig:X509Certificate>
</endpointHeaders>
</addressProperties>


I've got to say I don't understand this at all...or more to the point, don't see how it's viable. I believe what this is doing is providing the Identity of the service itself. Since this is statically declared in the clients config, it looks like a huge distribution issue. I'm sure microsoft must have something else in mind, like fetching this over ws-mex...anyone?

That pretty much covers what is required for the client and service config files - they're pretty close to the same. Next, we'll take a look at what happens when we invoke

And the Simple Indigo Client

Next, we need a simple client to go with my service.


using System;
using System.Collections.Generic;
using System.Text;

using System.Xml;
using System.ServiceModel;

namespace InfoCardClient
{

//This replicates the services contract - just raw Messages
[ServiceContract]
interface IGenericMessageChannel
{
[OperationContract(IsOneWay = true, Action = "*")]
void Send(Message msg);
}

class SimpleClient
{
public SimpleClient()
{
}

void SendMessage(IGenericMessageChannel channel, string input)
{
XmlDocument contentDocument;
contentDocument = new XmlDocument();
contentDocument.LoadXml("" + input + "");

XmlNodeReader content = new XmlNodeReader(contentDocument.DocumentElement);
MessageVersion messageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap11);

using (Message msg = Message.CreateMessage(messageVersion, "http://tempuri.org/ISimpleService/Receive", content))
{
try
{
channel.Send(msg);
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.ToString());
}

}
}

public void Invoke( string input)
{
using (ChannelFactory channelFactory =
new ChannelFactory("InfoCardClientConfig"))
{
channelFactory.Open();
IGenericMessageChannel channel = channelFactory.CreateChannel();
SendMessage(channel, input);
channelFactory.Close();
}
}
}
}


I call this client from another class which is irrelevant to the InfoCard/Indigo magic.

My Simple Indigo Service

Now onto some real infocard work. To begin with, I developed a simple webservice and client using Indigo. This service basically displays the raw SOAP which it is sent:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

//This is the Indigo namespace
using System.ServiceModel;
using System.Xml;

namespace InfoCardService
{
/**
Here, I'm using an interface to define the service contract.
Service contracts are explicit in Indigo, and can be distict
from application/class level contract as seen here.
*/
[ServiceContract]
interface ISimpleService
{
//A very raw service - interface accepts low level message type.
[OperationContract(IsOneWay = true)]
void Receive(System.ServiceModel.Message msg);
}


public partial class SimpleService : Form, ISimpleService
{
//selfhosting ServiceHost using generics to be types to my implementation
ServiceHost sh;

public SimpleService()
{
InitializeComponent();
}

private void button2_Click(object sender, EventArgs e)
{
sh.Close();
Application.Exit();
}

public void Receive(System.ServiceModel.Message msg)
{
MessageBox.Show("New Message:\n\n" + msg.ToString());
}

private void Start()
{
sh = new ServiceHost();
sh.Open();
}

static void Main(string[] args)
{
SimpleService service = new SimpleService();
service.Start();
Application.EnableVisualStyles();
Application.Run(service);
}

}
}

Invoking WS-Trust from Indigo

Making a WS-Trust RST Issue call from Indigo is pretty simple. I defined a custom security binding with a endpoint reference and presto...ws-trust.

To do this, I added this to the federationParameters section of a custom binding security element:

<endpoint address="http://192.168.9.10:8080/simpleservice" bindingConfiguration="WSTrustBinding" bindingSectionName="wsProfileBinding"/>

I then reference the binding from my client endpoint reference, and when I invoked my client, it makes this call:


POST /simpleservice HTTP/1.1
Content-Type: application/soap+xml; charset="utf-8" action="http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue"
Host: 192.168.9.11
Content-Length: 1304
Expect: 100-continue
Connection: Keep-Alive

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue</a:Action>
<a:MessageID>uuid:6e984807-8946-4201-a757-2b6829a5fdb4;id=0</a:MessageID>
<a:To s:mustUnderstand="1">http://192.168.9.10:8080/simpleservice</a:To>
<a:ReplyTo>
<a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
</a:ReplyTo>
</s:Header>
<s:Body>
<t:RequestSecurityToken Context="uuid-58ae93d3-a412-4ee4-97ab-288bc880b35a-2" xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
<t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
<t:BinaryExchange ValueType="http://schemas.microsoft.com/net/2004/07/secext/WS-SPNego">TlRMTVNTUAABAAAAt4IY4gAAAAAAAAAAAAAAAAAAAAAFAs4OAAAADw==</t:BinaryExchange>
<wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<EndpointReference xmlns="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:x="http://schemas.microsoft.com/2003/10/Serialization/">
<Address>http://192.168.9.10:8080/simpleservice</Address>
</EndpointReference>
</wsp:AppliesTo>
<t:KeySize>256</t:KeySize>
</t:RequestSecurityToken>
</s:Body></s:Envelope>


Looks to be using a web serivce binding of SPNego by default. I wish I had a remote STS to play with...

The InfoCard API

The InfoCard API is pretty straight forward (and I suspect in flux). There are only really 2 classes to pay attention to:

Microsoft.InfoCards.InfoCardClient


public static System.ServiceModel.Security.GenericXmlToken GetToken(System.ServiceModel.EndpointAddress endPoint, System.Collections.Generic.IEnumerable policy, System.Xml.XmlElement requiredRemoteTokenIssuer)

public static void Manage()


(Notice no constructor)

Microsoft.InfoCards.InfoCardTokenProvider


public override System.IAsyncResult BeginGetToken(System.ServiceModel.EndpointAddress target, System.AsyncCallback callback, object state)

public override System.ServiceModel.Security.Tokens.SecurityToken EndGetToken(System.IAsyncResult result)

public override System.ServiceModel.Security.Tokens.SecurityToken GetToken(System.ServiceModel.EndpointAddress target)

public InfoCardTokenProvider()

public override bool TryApplyIssuedTokenParameters(System.ServiceModel.Security.IIssuedTokenParameters parameters)

public override bool WillGetTokenCompleteSynchronously(System.ServiceModel.EndpointAddress target)



Besides that, it's all exceptions:
Microsoft.InfoCards.InfoCardException
Microsoft.InfoCards.NoDefaultCardException
Microsoft.InfoCards.ProvisioningCommunicationException
Microsoft.InfoCards.ServiceNotStartedException
Microsoft.InfoCards.StsCommunicationException
Microsoft.InfoCards.SuppressUIFailedException
Microsoft.InfoCards.UndisclosedClaimException
Microsoft.InfoCards.UnsupportedKeyGenerationTypeException
Microsoft.InfoCards.UntrustedRecipientException
Microsoft.InfoCards.UserCancellationException

A few other intersting things show up in the Indigo APIs:

Support for SAML, Kerb, X509, UserName, Windows, and WindowsUserName Tokens

Looks like support for April 04 and Feb 05 versions of WS-Trust

Today's barksdale-ism

Saturday, June 18, 2005

Programming InfoCard - part 1. Invoking the UI

Since I'm un-employed this weekend (I'm starting a new job at Sxip Identity on Monday), I thought I'd sit down and poke around the new Microsoft.InfoCards API and Indigo.

To start with, I suppose I'd better state up front that I haven't ever used Windows as my primary Desktop OS, and this is my first dive into C# as well. Fortunately, it seems to be enough of a Java clone that the learning curve is really quick...it feels a lot like Java 1.5.

Invoking the InfoCard UI:

My first step was to get the WinFX CTP and VisualStudio Betas installed. This was pretty straightforward, but make sure you have the latest of each, as there are some linking dependencies in the .NET build that require a specific combination. Also, I'd recommend the express version of Studio, as the full version is several GB.

To start out hacking with InfoCard, I thought I'd simply invoke the InfoCard UI. The simple way to do this is to hit the ControlPanel -> Digital identities. (Note that you can start the system by running: net start "InfoCard Service" at the command prompt if the system is not started for you) The result is the following wireframe UI:



Click for a larger version


It's also quite simple to invoke this via code. To do so, you can simply use the Manage() method on Microsoft.InfoCards.InfoCardClient. Simply create a new Console application, and add a reference to the Microsoft.InfoCards assembly. Then, the following code will invoke the InfoCardUI


using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.InfoCards;

namespace ManageInfoCard
{
class Program
{
static void Main(string[] args)
{
InfoCardClient.Manage();
}
}
}


That's all it takes to invoke the InfoCard system from code. More to come....

While you wait- here are some interesting links on Infocard, and Indigo which I found useful:

Indigo Docs on Infocard
A weekend with Indigo
Andy's InfoCard Blog
Simple Indigo Client
Simple Indigo Service

Daily Barksdale-ism

I recently ran across an old book of Barksdale-isms from Netscape. I thought I'd share some of the choice ones.

Today's - The three rules of snakes:



Tuesday, June 14, 2005

Tsunami!

Tsunami Alert in San Francisco - if there is one, it's will hit the bay at 9:24 tonight..

Monday, June 13, 2005

martha's vineyard

Mara and I just got back form a week on MV. I went a little crazy with the camera, and ended up with a flickr photoset that's 140+ large. Enjoy!

Tuesday, June 07, 2005

wisco represent

My good friend hamlett passed along some must haves for proud 'sconies: Illannoy.com

chappaquiddick

Congrats to Barrett and Anne!

Thursday, June 02, 2005

netscape directory...

...has finally gone open-source!

http://directory.fedora.redhat.com/wiki/Main_Page

It's refreshing to see something positive coming out of the ashes of Netscape - between embedding IE in Netscape 8, and the low-cost ISP ads...