{"id":535,"date":"2008-07-17T03:11:00","date_gmt":"2008-07-17T12:11:00","guid":{"rendered":"http:\/\/www.cloudidentity.com\/blog\/2008\/07\/17\/setting-up-a-quick-dirty-sts-which-supports-smartcard-backed-managed-cards-using-zermatt\/"},"modified":"2008-07-17T03:11:00","modified_gmt":"2008-07-17T12:11:00","slug":"setting-up-a-quick-dirty-sts-which-supports-smartcard-backed-managed-cards-using-zermatt","status":"publish","type":"post","link":"https:\/\/www.cloudidentity.com\/blog\/2008\/07\/17\/setting-up-a-quick-dirty-sts-which-supports-smartcard-backed-managed-cards-using-zermatt\/","title":{"rendered":"Setting up a quick &amp; dirty STS which supports smartcard backed managed cards&#8230; using Zermatt"},"content":{"rendered":"<p>Just back from vacation. The tan barely started to fade, and here I am already playing with the <a href=\"http:\/\/blogs.msdn.com\/vbertocci\/archive\/2008\/07\/09\/announcing-the-beta-release-of-zermatt-developer-identity-framework.aspx\">new shiny toy<\/a> :-). Did you experiment with <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkId=122266\">Zermatt<\/a> by now? As <a href=\"http:\/\/www.identityblog.com\/?p=1002\">Kim mentions<\/a> the samples (and the documentation) are an excellent way to start, and I am sure that blog posts &amp; tutorials will soon start mushrooming here and there in the blogosphere: here I begin my humble contribution with my first technical post about <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkId=122266\">Zermatt<\/a>.<\/p>\n<p>I had *absolutely* no hesitations when deciding which scenario I should tackle first: <strong><em>an active STS which handles requests backed by smartcards<\/em><\/strong>. I received asks about from many segments (especially about eID management from governments and high authentication levels for finance) and pretty much from everywhere in the world (especially Europe and Asia): I am really delighted to finally have a chance to give you something about that scenario that you can compile in visual studio, as opposed to the usual whiteboard sketches \ud83d\ude42<\/p>\n<p>Before we dive into the code, let me disclaim the disclaimable:<\/p>\n<ul>\n<li>as usual, the code you see in this blog is just an example and is <em>by no mean<\/em> production ready code. My purpose here is to introduce you to new ideas, so I favor readability and clarity over completeness <\/li>\n<li>If you consider the definition of <em>best practices<\/em> as <em>&#8220;A technique or methodology that, through experience and research, has proven to reliably lead to a desired result&#8221;<\/em>, I think I can safely say that there are no <em>established<\/em> best practices yet. Sure, there are some fixed points (use applyto, always check issuers &amp; revocations, encrypt &amp; sign as appropriate, sanitize everything including incoming claims&#8230;) and I am happy to share my experience here, but I think that the &#8220;experience and research&#8221; of you guys using the product in <u>your<\/u> business scenarios is what will drive the emergence of best practices. That&#8217;s why it&#8217;s so crucial that we get your feedback, and why you should not take what I write here as the golden standard and maintain a healthy skeptical attitude \ud83d\ude42<\/li>\n<\/ul>\n<p>Ooook, let&#8217;s get to work. We should start by better defining the problem: <strong>we want to develop a Security Token Service (STS) that can be invoked via WS-Trust (hence active); furthermore, we want our STS to process request for security token messages (RSTs) that have been secured by using a smartcard<\/strong>. Later we will also want to talk about managed cards, but let&#8217;s forget about that for the time being.<\/p>\n<p>&nbsp;<\/p>\n<h1>Active STS project structure in Zermatt<\/h1>\n<p>What is an active STS in Zermatt? You guessed right: <em>it is simply a WCF service<\/em>. Zermatt leverages the <a href=\"http:\/\/hyperthink.net\/blog\/of-hosts-and-factories\/\">factory based extensibility model of WCF<\/a> for hiding much of the protocol heavy lifting, and expects you to weave your custom logic by overriding specific methods in some derivation of a couple of base classes. Sounds complicated? On the contrary. Consider the diagram below:<\/p>\n<p><a href=\"http:\/\/blogs.msdn.com\/blogfiles\/vbertocci\/WindowsLiveWriter\/SettingupaquickdirtySTSwhic.usingZermatt_10447\/image_2.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right: 0px;border-top: 0px;border-left: 0px;border-bottom: 0px\" height=\"343\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2008\/07\/image_2.png\" width=\"504\" border=\"0\"><\/a> <\/p>\n<p>Those four files are the basis for the typical Zermatt active STS project. Let&#8217;s start from the right and move to the left:<\/p>\n<h3><strong>Service.svc<\/strong> and <strong>web.config<\/strong><\/h3>\n<p><strong> <\/p>\n<p><\/strong>We mentioned that an STS is a common WCF service: hence, we can describe it via a .svc file and associated web.config. The content of the .svc file will look like the following:<\/p>\n<pre class=\"code\"><span style=\"background: #ffee62\">&lt;%<\/span><span style=\"color: blue\">@<\/span><span style=\"color: #a31515\">ServiceHost  \r\n    <\/span><span style=\"color: red\">language<\/span><span style=\"color: blue\">=\"c#\"\r\n    <\/span><span style=\"color: red\">Factory<\/span><span style=\"color: blue\">=\"Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceHostFactory\" \r\n    <\/span><span style=\"color: red\">Service<\/span><span style=\"color: blue\">=\"MySTSConfig\" <\/span><span style=\"background: #ffee62\">%&gt;<\/span><\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<p>The Factory element uses <span style=\"color: blue\">WSTrustServiceHostFactory<\/span>, which is the factory offered by Zermatt for hosting STSes in IIS. The factory generates a service called <span style=\"color: blue\">Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceContract<\/span>, whose parameters can be influenced by creating the proper Service entry in the web.config: below there is a snippet of the first few lines of such config settings.<\/p>\n<pre class=\"code\"><span style=\"color: blue\">&lt;<\/span><span style=\"color: #a31515\">system.serviceModel<\/span><span style=\"color: blue\">&gt;\r\n    &lt;<\/span><span style=\"color: #a31515\">services<\/span><span style=\"color: blue\">&gt;\r\n      &lt;<\/span><span style=\"color: #a31515\">service <\/span><span style=\"color: red\">name<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceContract<\/span>\"\r\n         <span style=\"color: red\">behaviorConfiguration<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">MySTSBehavior<\/span>\"<span style=\"color: blue\">&gt;\r\n        &lt;<\/span><span style=\"color: #a31515\">endpoint <\/span><span style=\"color: red\">address<\/span><span style=\"color: blue\">=<\/span>\"\"\r\n                  <span style=\"color: red\">binding<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">customBinding<\/span>\"\r\n                  <span style=\"color: red\">bindingConfiguration<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">X509Binding<\/span>\"\r\n                  <span style=\"color: red\">contract<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">Microsoft.IdentityModel.Protocols.WSTrust.IWSTrustFeb2005SyncContract<\/span>\"<span style=\"color: blue\">\/&gt;\r\n        &lt;<\/span><span style=\"color: #a31515\">endpoint <\/span><span style=\"color: red\">address<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">https:\/\/localhost\/STS\/Service.svc\/Mex<\/span>\" <span style=\"color: red\">binding<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">mexHttpsBinding<\/span>\" <span style=\"color: red\">contract<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">IMetadataExchange<\/span>\"<span style=\"color: blue\">\/&gt;\r\n      &lt;\/<\/span><span style=\"color: #a31515\">service<\/span><span style=\"color: blue\">&gt;<\/span><\/pre>\n<pre class=\"code\"><span style=\"color: blue\">.....<\/span><\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<p>The Service element of the .svc file points to a custom class, that in the diagram I called STSConfig.<\/p>\n<h3>STSConfig.cs<\/h3>\n<p>The STS programming model requires you to derive a class from <span style=\"color: #2b91af\">SecurityTokenServiceConfiguration<\/span>: here we call the resulting subclass STSConfig. The purpose of this class is to gather in a single entity information that must be fed to the factory for instantiate the STS service, namely:<\/p>\n<ul>\n<li>intended address<\/li>\n<li>signing certificate<\/li>\n<li>custom issuance logic<\/li>\n<\/ul>\n<p>The last element is provided by referencing in STSConfig another custom class, here called MySTS.<\/p>\n<h3>MySTS.cs<\/h3>\n<p>The custom issuance logic is injected in the system by deriving from (surprise surprise) the class <span style=\"color: #2b91af\">SecurityTokenService<\/span>, and by overriding two methods: GetScope and GetOutputSubjects. We will see those in details later, however the former performs some validation and prepares some crypto necessary for the issuance while the latter contains the actual claim values retrieval logic.<\/p>\n<p>&nbsp;<\/p>\n<p>As you can see, this is not complicated at all. Let&#8217;s go ahead and apply the above for developing our smartcard based STS.<\/p>\n<h1>Writing the STS<\/h1>\n<p>Let&#8217;s start by firing up Visual Studio and creating a new web site; I suggest putting it in the local IIS and checking the &#8220;Use Secure Socket Layer&#8221; checkbox. In this example I called the IIS app &#8220;STS&#8221;.<\/p>\n<p><a href=\"http:\/\/blogs.msdn.com\/blogfiles\/vbertocci\/WindowsLiveWriter\/SettingupaquickdirtySTSwhic.usingZermatt_10447\/image_6.png\"><img loading=\"lazy\" decoding=\"async\" style=\"border-right: 0px;border-top: 0px;border-left: 0px;border-bottom: 0px\" height=\"323\" alt=\"image\" src=\"http:\/\/cloudidentity.com\/blog\/wp-content\/uploads\/2008\/07\/image_6.png\" width=\"485\" border=\"0\"><\/a> <\/p>\n<p>VS will create a Default.aspx page for you: ignore it for now, but don&#8217;t delete it: it will come in handy in the next post.<\/p>\n<p>We have seen in the former section what are the files that are needed for defining an STS. Let&#8217;s create those files in reverse order: we will start from MySTS.cs.<\/p>\n<p>Add a reference to System.ServiceUtil and Microsoft.IdentityModel; add the App_Code ASP.NET folder to the web site, and add to it a copy of CertificateUtil.cs (you can find it in the C:&lt;Program Files&gt;Microsoft Code Name ZermattSamplesBasicActiveSTSWithManagedCard sample); then, create the file MySTS.cs.<\/p>\n<h3>MySTS.cs<\/h3>\n<p>The using blocks, class declaration &amp; constructor look like the following:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">using <\/span>System.Collections.Generic;\r\n<span style=\"color: blue\">using <\/span>System.Security.Cryptography.X509Certificates;\r\n<span style=\"color: blue\">using <\/span>System.ServiceModel;\r\n\r\n<span style=\"color: blue\">using <\/span>Microsoft.IdentityModel.Claims;\r\n<span style=\"color: blue\">using <\/span>Microsoft.IdentityModel.Configuration;\r\n<span style=\"color: blue\">using <\/span>Microsoft.IdentityModel.Services;\r\n<span style=\"color: blue\">using <\/span>Microsoft.IdentityModel.Services.SecurityTokenService;\r\n<span style=\"color: blue\">using <\/span>Microsoft.IdentityModel.Protocols.WSIdentity;\r\n<span style=\"color: blue\">using <\/span>System.Runtime.Remoting.Metadata.W3cXsd2001;\r\n<span style=\"color: blue\">using <\/span>System.Linq;\r\n\r\n\r\n<span style=\"color: blue\">public class <\/span><span style=\"color: #2b91af\">MySTS <\/span>: <span style=\"color: #2b91af\">SecurityTokenService\r\n<\/span>{\r\n    <span style=\"color: blue\">public <\/span>MySTS(<span style=\"color: #2b91af\">SecurityTokenServiceConfiguration <\/span>config)\r\n        : <span style=\"color: blue\">base<\/span>(config)\r\n    {\r\n    }\r\n<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<blockquote>\n<p>Nothing transcendental here. We use a bunch of namespaces, we derive from <span style=\"color: #2b91af\">SecurityTokenService <\/span>and we just call the base constructor. Then we finally start doing something interesting: remember the overrides I mentioned before? The first one we will implement is GetScope. GetScope takes care of verifying that we are happy with the RP for which the subject is requesting a token. Let&#8217;s take a look at the code:<\/p>\n<\/blockquote>\n<pre class=\"code\"><span style=\"color: gray\">    \/\/\/ &lt;summary&gt;\r\n    \/\/\/ <\/span><span style=\"color: green\">verifies that the intended RP is one for which we are willing to issue a token;\r\n    <\/span><span style=\"color: gray\">\/\/\/ <\/span><span style=\"color: green\">retrieves the corresponding certificate so that the resulting token can be encrypted accordingly\r\n    <\/span><span style=\"color: gray\">\/\/\/ &lt;\/summary&gt;\r\n    <\/span><span style=\"color: blue\">protected override <\/span><span style=\"color: #2b91af\">Scope <\/span>GetScope(<span style=\"color: #2b91af\">IClaimsPrincipal <\/span>principal, <span style=\"color: #2b91af\">RequestSecurityToken <\/span>request)\r\n    {\r\n        <span style=\"color: green\">\/\/base\r\n        <\/span><span style=\"color: #2b91af\">Scope <\/span>scope = <span style=\"color: blue\">base<\/span>.GetScope(principal, request);\r\n        <span style=\"color: green\">\/\/checks if we are happy with the intended RP\r\n        <\/span>ValidateAppliesTo(request.AppliesTo);\r\n        <span style=\"color: green\">\/\/retrieves the corresponding cert and embeds it in the scope\r\n        <\/span><span style=\"color: blue\">string <\/span>RPhostname = request.AppliesTo.Uri.Host;\r\n        scope.EncryptingCredentials = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">X509EncryptingCredentials<\/span>(<span style=\"color: #2b91af\">CertificateUtil<\/span>.GetCertificate(<span style=\"color: #2b91af\">StoreName<\/span>.My, <span style=\"color: #2b91af\">StoreLocation<\/span>.LocalMachine, <span style=\"color: #a31515\">\"CN=\" <\/span>+ RPhostname));\r\n\r\n        <span style=\"color: blue\">return <\/span>scope;\r\n    }<\/pre>\n<blockquote>\n<pre class=\"code\">&nbsp;<\/pre>\n<\/blockquote>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<blockquote>\n<p>The input parameters are the principal of the requestor (the subject) and the request itself, already nicely deserialized an a handy class (the heroic pioneers of the do-it-yourself STS era can tell you how much code that takes if you have to do it by hand).<\/p>\n<p>Here we mainly want to do 2 things:<\/p>\n<ol>\n<li>we want to make sure that the requested token is scoped for an RP that we like. That means that we need to verify that we have a non empty ApplyTo in the request, and that its content matches one entry in our list of approved RPs. The call to ValidateAppliesTo takes care of it<\/li>\n<li>We want to make sure that the token we will issue will be encrypted for the intended RP: that means retrieving the certificate associated to the RP and assigning it to the EncryptingCredentials element of our current scope. The code that performs this is pretty self explanatory, if a bit crude: we assume to have in our LocalMachine cert store certificates following the convention &#8220;CN=RPhostname&#8221;<\/li>\n<\/ol>\n<\/blockquote>\n<blockquote>\n<p>An example of ValidatesApplyTo can be easily obtained from the above mentioned example ActiveSTSWithManagedCard.<\/p>\n<p>Before we move on, let me make a couple of comments:<\/p>\n<ul>\n<li>The fact that we mandate the presence of ApplyTo is a good practice, but it is by no mean an universal rule. A non-auditing STS would not need (or even want) an ApplyTo.<\/li>\n<li>The cert that goes in EncryptingCredentials here comes from the local cert store; however it is also possible to take the cert that is sent in the request, and use that instead of requiring the corresponding certificate to be present in the local store from a prior time. The tradeoff is, naturally, agility vs. security.<\/li>\n<li>Some would advocate that GetScope should contain also the subject authentication logic (that is, if that logic didn&#8217;t run even before reaching the MySTS class). That makes a lot of sense, and would also justify the presence of the principal parameter; GetScope is the first override that is invoked in the request processing pipeline, hence if the user didn&#8217;t present valid credentials the sooner we fail the less resources we waste. On the other hand it seems that GetScope is about &#8220;validating&#8221; the RP, hence putting user auth logic there may be perceived as a side effect. For the clarity vs. completeness tenet introduced above, here I keep GetScope focused on RP related tasks and perform subject authentication elsewhere; however I invite you to ponder the considerations in this bullet point, and make decisions accordingly in your own projects.<\/li>\n<\/ul>\n<\/blockquote>\n<blockquote>\n<p>The next method is GetOutputSubject: as mentioned, its purpose is to actually fetch the claim values requested. Here there&#8217;s the code:<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"code\"><span style=\"color: gray\">\/\/\/ &lt;summary&gt;\r\n\/\/\/ <\/span><span style=\"color: green\">authenticates the user requesting the token\r\n<\/span><span style=\"color: gray\">\/\/\/ <\/span><span style=\"color: green\">retrieves the values of the requested claims\r\n<\/span><span style=\"color: gray\">\/\/\/ &lt;\/summary&gt;\r\n<\/span><span style=\"color: blue\">public override <\/span><span style=\"color: #2b91af\">ClaimsIdentityCollection <\/span>GetOutputSubjects(<span style=\"color: #2b91af\">Scope <\/span>scope, <span style=\"color: #2b91af\">IClaimsPrincipal <\/span>principal, \r\n    <span style=\"color: #2b91af\">RequestSecurityToken <\/span>request)\r\n{        \r\n    <span style=\"color: green\">\/\/verifies that the incoming RST has been secured by one smartcard among the ones we recognize\r\n    <\/span>AuthenticateCredentials((<span style=\"color: #2b91af\">IClaimsIdentity<\/span>)principal.Identity);\r\n\r\n    <span style=\"color: green\">\/\/goes through the list of requested claims and retrieves the corresponding values from the stores\r\n    <\/span><span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">Claim<\/span>&gt; claims = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">List<\/span>&lt;<span style=\"color: #2b91af\">Claim<\/span>&gt;();\r\n    <span style=\"color: blue\">foreach <\/span>(<span style=\"color: #2b91af\">RequestClaim <\/span>requestClaim <span style=\"color: blue\">in <\/span>request.Claims)\r\n    {\r\n        claims.Add(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">Claim<\/span>(requestClaim.ClaimType, RetrieveClaimValue(principal, requestClaim.ClaimType)));            \r\n    }\r\n    <span style=\"color: #2b91af\">ClaimsIdentityCollection <\/span>collection = <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">ClaimsIdentityCollection<\/span>();\r\n    collection.Add(<span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">ClaimsIdentity<\/span>(claims));\r\n\r\n    <span style=\"color: blue\">return <\/span>collection;\r\n}<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p><\/blockquote>\n<blockquote>\n<p>The parameters are the same ones of GetScope, plus the Scope itself.<\/p>\n<p>The first thing we do is authenticating the incoming subject, by examining the incoming principal (for details on the principal-claims structures, see Keith&#8217;s whitepaper). Here there&#8217;s the code of AuthenticateCredentials:<\/p>\n<pre class=\"code\"><span style=\"color: gray\">  \/\/\/ &lt;summary&gt;\r\n  \/\/\/  <\/span><span style=\"color: green\">verifies that the incoming RST was secured by the certificate associated to the managed card we generated;\r\n<\/span><span style=\"color: gray\">  \/\/\/  <\/span><span style=\"color: green\">normally this check would be performed against a database, here it's all hardcoded\r\n<\/span><span style=\"color: gray\">  \/\/\/ &lt;\/summary&gt;\r\n<\/span><span style=\"color: blue\">  void <\/span>AuthenticateCredentials(<span style=\"color: #2b91af\">IClaimsIdentity <\/span>cert)\r\n  {\r\n      <span style=\"color: blue\">string <\/span>thumbstring = (<span style=\"color: blue\">from <\/span>c <span style=\"color: blue\">in <\/span>cert.Claims\r\n                            <span style=\"color: blue\">where <\/span>c.ClaimType == <span style=\"color: #2b91af\">WSIdentityConstants<\/span>.<span style=\"color: #2b91af\">ClaimTypes<\/span>.Thumbprint\r\n                            <span style=\"color: blue\">select <\/span>c.Value).Single();\r\n      <span style=\"color: blue\">string <\/span>savedthumb = System.<span style=\"color: #2b91af\">Convert<\/span>.ToBase64String(<span style=\"color: #2b91af\">SoapHexBinary<\/span>.Parse(<span style=\"color: #a31515\">\"xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx\"<\/span>).Value); \r\n      <span style=\"color: blue\">if <\/span>(thumbstring != savedthumb)\r\n      {\r\n          <span style=\"color: blue\">throw new <\/span><span style=\"color: #2b91af\">FailedAuthenticationException<\/span>(<span style=\"color: #a31515\">\"The certificate credentials you presented are not recognized.\"<\/span>);\r\n      }\r\n  }<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p><\/blockquote>\n<blockquote>\n<p>This is the first time that we have any technology specific code. Here I assume that the incoming IClaimsIdentity has been created from an X509 certificate; hence I use a Linq expression for retrieving the base64 encoding of the incoming certificate thumbprint (do you have feedback about the logic we use for accessing claims?). The savedthumb assignment line is a terrible hack and a sublime trick at the same time. Here I am basically establishing what is the certificate that I am willing to accept: the way in which I obtain it is 1) going to the certificate MMC, selecting the certificate of the smartcard I am willing to accept and copying the thumbprint string from the cert properties dialog (the &#8220;xx xx ..&#8221; censored string above) and 2) using this arcane <span style=\"color: #2b91af\">SoapHexBinary<\/span>.Parse method (from the esoteric System.Runtime.Remoting.Metadata.W3cXsd2001 namespace) which chews a hex string and gives back bytes[].<\/p>\n<p>If the 2 thumbprints correspond, this means that the request was secured by using the smartcard I chose hence the user is authenticated. Obviously a real system would have a database of accepted smartcards\/soft certificates.<\/p>\n<p>Back to GetOutputSubjects: the central foreach goes through the claims requested in the RST and retrieves the corresponding value. Note that here I don&#8217;t handle optional claims for the sake of clarity, you can refer to the ActiveSTSWithManagedCard sample if you are curious about it. The retrieving legwork is performed by the helper function RetrieveClaimValue: the code is below.<\/p>\n<pre class=\"code\"><span style=\"color: gray\">\/\/\/ &lt;summary&gt;\r\n\/\/\/ <\/span><span style=\"color: green\">retrieves the value of a claim associated to a certain principal\r\n<\/span><span style=\"color: gray\">\/\/\/ &lt;\/summary&gt;\r\n<\/span><span style=\"color: blue\">private string <\/span>RetrieveClaimValue(<span style=\"color: #2b91af\">IClaimsPrincipal <\/span>principal, <span style=\"color: blue\">string <\/span>claimType)\r\n{\r\n    <span style=\"color: green\">\/\/here I would normally use something of the principal for looking up attributes values in one (or more) stores\r\n    \/\/here i ignore it and return hardcoded values\r\n    <\/span><span style=\"color: blue\">switch <\/span>(claimType)\r\n    {\r\n        <span style=\"color: blue\">case <\/span><span style=\"color: #2b91af\">WSIdentityConstants<\/span>.<span style=\"color: #2b91af\">ClaimTypes<\/span>.DateOfBirth: <span style=\"color: blue\">return <\/span><span style=\"color: #a31515\">\"01\/30\/70\"<\/span>;\r\n        <span style=\"color: blue\">case <\/span><span style=\"color: #2b91af\">WSIdentityConstants<\/span>.<span style=\"color: #2b91af\">ClaimTypes<\/span>.Name: <span style=\"color: blue\">return <\/span><span style=\"color: #a31515\">\"Gion\"<\/span>;\r\n        <span style=\"color: blue\">case <\/span><span style=\"color: #a31515\">\"http:\/\/www.maseghepensu.it\/hairlenght\"<\/span>: <span style=\"color: blue\">return <\/span><span style=\"color: #a31515\">\"50\"<\/span>;\r\n        <span style=\"color: blue\">default<\/span>: <span style=\"color: blue\">throw new <\/span><span style=\"color: #2b91af\">InvalidRequestException<\/span>(claimType + <span style=\"color: #a31515\">\" is not a claim issued by this STS.\"<\/span>);\r\n    }\r\n}<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p><\/blockquote>\n<blockquote>\n<p>A real attribute retrieval function would use the principal for querying an attribute store (or more than one) and return the value of the requested claim for that specific user. Here we don&#8217;t do that, in fact we just have 3 hardcoded values that correspond to 3 claim types. Those claim types are the ones that our STS will support; the first 2 are the common DateOfBirth and Name, the third one is the classic custom claim that I use in every sts sample:&nbsp; HairLenght. Any request asking for a claim that does not belong to this set of three would get an InvalidRequestException.<\/p>\n<\/blockquote>\n<p>That&#8217;s all: all our custom logic is there, the rest is just infrastructure.<\/p>\n<h3>MySTConfig.cs<\/h3>\n<p>Create the file MySTSConfig.cs, and paste in it the following:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">using <\/span>System.Security.Cryptography.X509Certificates;\r\n<span style=\"color: blue\">using <\/span>Microsoft.IdentityModel.Configuration;\r\n<span style=\"color: blue\">using <\/span>Microsoft.IdentityModel.Services.SecurityTokenService;\r\n\r\n<span style=\"color: gray\">\/\/\/ &lt;summary&gt;\r\n\/\/\/ <\/span><span style=\"color: green\">Summary description for SecurityTokenServiceConfiguration\r\n<\/span><span style=\"color: gray\">\/\/\/ &lt;\/summary&gt;\r\n<\/span><span style=\"color: blue\">public class <\/span><span style=\"color: #2b91af\">MySTSConfig <\/span>: <span style=\"color: #2b91af\">SecurityTokenServiceConfiguration\r\n<\/span>{\r\n    <span style=\"color: blue\">public const string <\/span>issuerAddress = <span style=\"color: #a31515\">\"http:\/\/localhost\/STS\/Service.svc\"<\/span>;\r\n\r\n    <span style=\"color: blue\">public <\/span>MySTSConfig()\r\n        : <span style=\"color: blue\">base<\/span>(issuerAddress, <span style=\"color: blue\">new <\/span><span style=\"color: #2b91af\">X509SigningCredentials<\/span>(<span style=\"color: #2b91af\">CertificateUtil<\/span>.GetCertificate(<span style=\"color: #2b91af\">StoreName<\/span>.My, <span style=\"color: #2b91af\">StoreLocation<\/span>.LocalMachine, <span style=\"color: #a31515\">\"CN=localhost\"<\/span>)))\r\n    {\r\n        SecurityTokenService = <span style=\"color: blue\">typeof<\/span>(<span style=\"color: #2b91af\">MySTS<\/span>);\r\n    }\r\n}\r\n<\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<p>This is exactly as we described in the STS project structure section: our custom config class assigns a name to the issuer, establishes which certificate will be used for signing the issued tokens and embeds our custom logic by assigning the MySTS type to the SecurityTokenService that will be instantiated by the factory.<\/p>\n<h3>Service.svc<\/h3>\n<p>Create the Service.svc file and paste in it the lines we already saw: <\/p>\n<pre class=\"code\"><span style=\"background: #ffee62\">&lt;%<\/span><span style=\"color: blue\">@<\/span><span style=\"color: #a31515\">ServiceHost  \r\n    <\/span><span style=\"color: red\">language<\/span><span style=\"color: blue\">=\"c#\"\r\n    <\/span><span style=\"color: red\">Factory<\/span><span style=\"color: blue\">=\"Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceHostFactory\" \r\n    <\/span><span style=\"color: red\">Service<\/span><span style=\"color: blue\">=\"MySTSConfig\" <\/span><span style=\"background: #ffee62\">%&gt;<\/span><\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<h3>web.config<\/h3>\n<p>The last piece we need for completing our STS is the service configuration. The web site already has a web.config file: we just need to add a serviceModel section to it, so that we can associate to the <span style=\"color: blue\">Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceContract<\/span> service a binding suitable for invoking the service by using a smartcard (or soft cert) as credentials. Below there is the excerpt of the serviceModel section:<\/p>\n<pre class=\"code\"><span style=\"color: blue\">&lt;<\/span><span style=\"color: #a31515\">system.serviceModel<\/span><span style=\"color: blue\">&gt;\r\n    &lt;<\/span><span style=\"color: #a31515\">services<\/span><span style=\"color: blue\">&gt;\r\n      &lt;<\/span><span style=\"color: #a31515\">service <\/span><span style=\"color: red\">name<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceContract<\/span>\"\r\n         <span style=\"color: red\">behaviorConfiguration<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">MySTSBehavior<\/span>\"<span style=\"color: blue\">&gt;\r\n        &lt;<\/span><span style=\"color: #a31515\">endpoint <\/span><span style=\"color: red\">address<\/span><span style=\"color: blue\">=<\/span>\"\"\r\n                  <span style=\"color: red\">binding<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">customBinding<\/span>\"\r\n                  <span style=\"color: red\">bindingConfiguration<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">X509Binding<\/span>\"\r\n                  <span style=\"color: red\">contract<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">Microsoft.IdentityModel.Protocols.WSTrust.IWSTrustFeb2005SyncContract<\/span>\"<span style=\"color: blue\">\/&gt;\r\n        &lt;<\/span><span style=\"color: #a31515\">endpoint <\/span><span style=\"color: red\">address<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">https:\/\/localhost\/STS\/Service.svc\/Mex<\/span>\" <span style=\"color: red\">binding<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">mexHttpsBinding<\/span>\" <span style=\"color: red\">contract<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">IMetadataExchange<\/span>\"<span style=\"color: blue\">\/&gt;\r\n      &lt;\/<\/span><span style=\"color: #a31515\">service<\/span><span style=\"color: blue\">&gt;\r\n    &lt;\/<\/span><span style=\"color: #a31515\">services<\/span><span style=\"color: blue\">&gt;\r\n    &lt;<\/span><span style=\"color: #a31515\">bindings<\/span><span style=\"color: blue\">&gt;\r\n      &lt;<\/span><span style=\"color: #a31515\">customBinding<\/span><span style=\"color: blue\">&gt;\r\n        &lt;<\/span><span style=\"color: #a31515\">binding <\/span><span style=\"color: red\">name<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">X509Binding<\/span>\"<span style=\"color: blue\">&gt;\r\n          &lt;<\/span><span style=\"color: #a31515\">security <\/span><span style=\"color: red\">authenticationMode<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">MutualCertificate<\/span>\" <span style=\"color: blue\">\/&gt;\r\n          &lt;<\/span><span style=\"color: #a31515\">httpTransport <\/span><span style=\"color: blue\">\/&gt;\r\n        &lt;\/<\/span><span style=\"color: #a31515\">binding<\/span><span style=\"color: blue\">&gt;\r\n      &lt;\/<\/span><span style=\"color: #a31515\">customBinding<\/span><span style=\"color: blue\">&gt;\r\n    &lt;\/<\/span><span style=\"color: #a31515\">bindings<\/span><span style=\"color: blue\">&gt;\r\n    &lt;<\/span><span style=\"color: #a31515\">behaviors<\/span><span style=\"color: blue\">&gt;\r\n      &lt;<\/span><span style=\"color: #a31515\">serviceBehaviors<\/span><span style=\"color: blue\">&gt;\r\n        &lt;<\/span><span style=\"color: #a31515\">behavior <\/span><span style=\"color: red\">name<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">MySTSBehavior<\/span>\"<span style=\"color: blue\">&gt;\r\n          &lt;<\/span><span style=\"color: #a31515\">serviceMetadata <\/span><span style=\"color: red\">httpGetEnabled<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">true<\/span>\"<span style=\"color: blue\">\/&gt;\r\n          &lt;<\/span><span style=\"color: #a31515\">serviceDebug <\/span><span style=\"color: red\">includeExceptionDetailInFaults<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">true<\/span>\"<span style=\"color: blue\">\/&gt;\r\n          &lt;<\/span><span style=\"color: #a31515\">serviceCredentials<\/span><span style=\"color: blue\">&gt;\r\n            &lt;<\/span><span style=\"color: #a31515\">serviceCertificate <\/span><span style=\"color: red\">findValue<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">localhost<\/span>\"\r\n                     <span style=\"color: red\">storeLocation<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">LocalMachine<\/span>\"\r\n                     <span style=\"color: red\">storeName<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">My<\/span>\"\r\n                     <span style=\"color: red\">x509FindType<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">FindBySubjectName<\/span>\" <span style=\"color: blue\">\/&gt;\r\n\r\n            &lt;<\/span><span style=\"color: #a31515\">issuedTokenAuthentication <\/span><span style=\"color: red\">allowUntrustedRsaIssuers<\/span><span style=\"color: blue\">=<\/span>\"<span style=\"color: blue\">true<\/span>\" <span style=\"color: blue\">\/&gt;\r\n          &lt;\/<\/span><span style=\"color: #a31515\">serviceCredentials<\/span><span style=\"color: blue\">&gt;\r\n        &lt;\/<\/span><span style=\"color: #a31515\">behavior<\/span><span style=\"color: blue\">&gt;\r\n      &lt;\/<\/span><span style=\"color: #a31515\">serviceBehaviors<\/span><span style=\"color: blue\">&gt;\r\n    &lt;\/<\/span><span style=\"color: #a31515\">behaviors<\/span><span style=\"color: blue\">&gt;\r\n  &lt;\/<\/span><span style=\"color: #a31515\">system.serviceModel<\/span><span style=\"color: blue\">&gt;<\/span><\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<p>Looks familiar? It should. It is pretty much the same config we were using with the simpleSTS.<\/p>\n<h1>Next steps<\/h1>\n<p>We are done! The steps above were enough for setting up a fully functional, albeit simple, active STS which authenticates request for security tokens secured via smartcard\/soft certificates. Now we need to test it: in the next couple of posts we will<\/p>\n<ol>\n<li>Add UI and logic for issuing cards associated to this STS and backed by smartcards<\/li>\n<li>Create an RP that will require tokens from our STS<\/li>\n<\/ol>\n<p>As you can imagine, both tasks are going to be much easier that the already semi-trivial tutorial described in this post. At the end of the series I&#8217;ll probably post as attachment the complete solution. <\/p>\n<p>Well, that was FUN! Would you have ever imagined that one day we would say that about <em>writing an STS<\/em>? \ud83d\ude09 hehehe<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Just back from vacation. The tan barely started to fade, and here I am already playing with the new shiny toy :-). Did you experiment with Zermatt by now? As Kim mentions the samples (and the documentation) are an excellent way to start, and I am sure that blog posts &amp; tutorials will&#8230;<\/p>\n","protected":false},"author":1,"featured_media":1452,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"footnotes":""},"categories":[61,39,9,86,64,55,31,79],"tags":[],"class_list":["post-535","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-architecture-ws","category-cardspace","category-identity","category-infocard","category-wcf","category-windows-cardspace","category-windows-communication-foundation","category-zermatt"],"_links":{"self":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/535","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/comments?post=535"}],"version-history":[{"count":0,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/535\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media\/1452"}],"wp:attachment":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media?parent=535"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/categories?post=535"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/tags?post=535"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}