Showing posts with label WS-Federation. Show all posts
Showing posts with label WS-Federation. Show all posts

Thursday, January 19, 2012

Custom ADFS Login Form for SharePoint 2010 Claims

This week I've been involved in creating a custom login page for SharePoint 2010 to bypass the standard "select a login method" page for multi-mode claims-enabled web-applications. What we wanted was similar to the Claims Login Web Part for SharePoint Server 2010 for Forms-Based Authentication (FBA) by Jeremy Jameson, but for a trusted ADFS 2.0 identity provider instead.


Having a custom login page allows you to stay in your site and avoid the passive STS authN redirect dance back and forth between SP and the ADFS STS for authentication. This requires you to use active mode (WS-Trust) rather than the passive mode used by SharePoint. Note that this active approach won't give you single sign-on, because you won't get the MSISAuth ADFS SSO cookies - it will simply authenticate you first and then give you the SharePoint FedAuth cookie.

The code you need to call ADFS to make it authenticate you, and thus issue a claims token for use with SharePoint, can be found at Using an Active Endpoint to sign into a Web Application by Dominick Baier or Making a web application use an active STS by Koen Willemse. The missing detail not shown in their code is the URL to the ADFS endpoint, which needs to match the chosen client credentials and security mode; when using UserNameWSTrustBinding and sending the username and password in the WCF message secured using SSL (i.e. mixed), the URL should be like "http://adfs.pzl/adfs/services/trust/13/usernamemixed/" including the important ending / slash to avoid "405 method not allowed" error from IIS.

protected void btnLogin_Click(object sender, EventArgs e)
{
    // authenticate with WS-Trust endpoint
    var factory = new WSTrustChannelFactory(
        new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
        new EndpointAddress(
"https://adfs.puzzlepart.com/adfs/services/trust/13/usernamemixed/"));
 
 
    factory.Credentials.UserName.UserName = txtUserName.Text;
    factory.Credentials.UserName.Password = txtPassword.Text;
 
    var channel = factory.CreateChannel();
 
    var rst = new RequestSecurityToken
    {
        RequestType = RequestTypes.Issue,
        AppliesTo = new EndpointAddress("urn:sharepoint:puzzlepart"),
        KeyType = KeyTypes.Bearer
    };
 
    var genericToken = channel.Issue(rst) as GenericXmlSecurityToken;
 
 
    // parse token
    var handlers = FederatedAuthentication.ServiceConfiguration
.SecurityTokenHandlers;
    var token = handlers.ReadToken(new XmlTextReader(
       new StringReader(genericToken.TokenXml.OuterXml)));
         
    SPSecurity.RunWithElevatedPrivileges(delegate(){
        SPFederationAuthenticationModule.Current
.SetPrincipalAndWriteSessionToken(token);
    });
    Response.Redirect("~/pages/default.aspx");
}

After getting authenticated against the ADFS STS when calling Issue on the WS-Trust channel with a RequestSecurityToken, the returned SAML security token must first be parsed and then written to a FedAuth cookie created from the SAML token. The SharePoint FAM wrapper will both set the thread principal and write the cookie, making the user a logged in SharePoint user.

Note how the writing of the cookie is wrapped with RunWithElevatedPrivileges to ensure that  it runs as the app-pool identity and not as the impersonated SharePoint user. This is to avoid the dreaded "CryptographicException: The system cannot find the file specified" error in the internal ProtectedDataCookieTransform call.

When calling ValidateToken you will run into the SecurityTokenException: Issuer of the Token is not a Trusted Issuer error if your STS is not trusted by SharePoint. SharePoint is configured to use its own SPPassiveIssuerNameRegistry and that will either validate against the built-in SharePoint STS or the set of trusted STS token issuers. See how to add your STS certificate(s) at SharePoint 2010 Claims-Based Auth with ADFS v2 by Eric Kraus. The trusted providers are apparently only used if the login page is located under the /_trust/ folder that is part of the above "redirect dance" when authenticating against a trusted identity provider.

Over at stack overflow, Matt Whetton had run into the same exception as us and solved it by replacing the passive <issuerNameRegistry> with the Windows Identity Foundation (WIF) ConfigurationBasedIssuerNameRegistry instead. The Configuration of WIF post shows how to add the set of certificate names and thumbprints to the <trustedIssuers> list. This is how your web.config list of trusted STS token issuers may look like:

<issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, 
Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"> 
  <trustedIssuers> 
    <add thumbprint="1337133713371337" name="CN=adfs-puzzlepart" /> 
    <add thumbprint="0000000000000000" name="CN=SharePoint Security Token Service" />
  </trustedIssuers> 
</issuerNameRegistry> 

Remember to add the SharePoint self-issued certificates such as the "SharePoint Security Token Service" certificate to the list of trusted issuers, in addition to your own STS.

I strongly recommend putting your custom ADFS login page under /_trust/ to avoid having to change the SharePoint web.config files. We chose this approach to minimize risks.

Note that Fiddler seems to break the ADFS login process, at least when decrypting SSL. The customized rule provided in Fiddler and Channel Binding Tokens Revisited by Eric Lawrence alleviates this problem. Just make sure you click "remember my credentials" when logging in so that Fiddler can get it from the Windows Credential Manager.

Disclaimer: Note that even if things seems to work as normal after this configuration change, there is no guarantee that nothing was affected in the huge platform that SharePoint 2010 is. The combination of SP2010 claims and WIF is not very well documented, and any changes beyond supported configuration involves risks. Do not apply these changes if you are not sure that it will not break any of your SharePoint solutions or services.

Sunday, May 04, 2008

On Tokens, Claims, Tickets, SAML

There always seems to be a lot of confusion about tokens, tickets, and claims; which in combination with the very broad term security (authN, authZ, confidentiality, integrity, auditing, devices, data, etc) make every discussion about "security" a bit obscure.

A simple explanation of tokens and claims: a Security Token is a signed and encrypted set of Claims. A claim is just some right on a specific resource of a given resource type that the token holder claims to have. To accept this claim, you need to trust the token issuer. The typical example of a claim is the user's identity (the claim), which e.g. can be the domain login name (the resource) asserted by Windows (the issuer).

The terms Security Token and Claim are used in the WS-Trust standard. Kerberos use the term ticket instead of token, i.e. the ticket proves the identity of the user. A SAML token is another type of security token.

Watch the Channel9 video where Vittorio Bertocci explains WS-Trust and the token encryption and signing mechanism in depth, using a claim set based on a driver license resource. Note that only video download seems to work.

In addition, read the post series by Sam Gentile about SAML, which expands into claims-based security and WS-Trust / WS-Federation.

Wednesday, January 30, 2008

Ontology for Business Processes, SOA and Information Models

I have for a long time promoted that you should apply a specific kind of information model (the business process information model - BPIM) when composing services into business processes in service oriented solutions. A BPIM models the messages for the business events that drive the business processes. The main goal of this information model is to enable coordinated loose-coupling (semantic mediation) between the services at the composition level.

There has been a lot of discussions on how the BPIM relates to SOA services and the common information model (CIM), and how the BPM process layer relates to the SOA process layer. In the following ontology I have tried to model the relationships between the documents and the domain objects, Shy Cohen’s service taxonomy & ontology, and Jean-Jacques Dubray’s SOA+BPM ontology

The service classification scheme has the "hierarchy" taxomomy form. It is not a scientific hierarchy nor a tree form, thus there is no "is using" or "is dependent on" relation between the services - it is just a classification scheme. There can be no dependency between services in SOA except for composite services realizing a business process by consuming the actual services. Taking a dependency on another service will break the central "services are autonomous" tenet of SOA.

Click to enlarge the ontology:

Note how there are processes at two levels in the model: the event-driven resource lifecycle processes for domain objects (bottom), and the human-driven business processes realized as composed services (top). These two levels are separate bounded contexts with well defined mappings between them: the business process domain and the resource lifecycle domain.

The BPIM is applied at the business process domain level (orchestrations / composites / sagas), while the services operate on the domain objects in the CIM to manage the lifecycle of these resources in accordance with the business events.

Note that the BPIM is related to, and is a subset of/reference to, the resource domain objects in the common information model (CIM). In addition, the messages covers more than just activity data, they also contain queries, notifications (events) and commands. This in like a mail order paper form that contains e.g. some customer data and references to product data. The word "subset" is central, e.g. the “customer has moved” action event has a BPIM document that contains the data pertinent to that specific business process event, not the complete schema of the customer domain object. The resource process service used to act on the “customer has moved” event does of course operate on the actual domain object, but this is invisible to the human workflow process.

The business process messages (action, query, notification) driving the composite services and the resulting business events are central artifacts when designing the services and the information model. I am a strong believer in designing a service-oriented solution by applying "EDA style" thinking to avoid missing out on the events and their documents due to traditional “invoke operations” SOA thinking, getting too much focus on business process flow.

An aspect not shown in the model is that the need for agility increases towards the top, while the cost of change increases towards the bottom. This is an important argument for having processes at two levels; it allows you to contain the frequent changes to the business processes (mashup style compositions) and composite services rather than having to constantly make changes to the services themselves, which could become very costly as the number of service subscribers increases over time. This is something that your business people should readily appreciate.

Design your system to have flexibility in the flow of the business processes and composite services. The diamonds of your business process are the business decisions, and this is where you should implement a business rules engine (BRE) mechanism. Process flow logic is not service business logic, avoid leaking domain logic into the orchestration layer at all cost.

Finally, the model show how claims relate to services at all levels. I have done this to show how a claims-based security model is a cross-cutting concern throughout a service-oriented solution. I strongly recommend designing in process claims right from the beginning, as this makes it easier to learn how access control relates to the business processes and solution domain.

Master Data Management (MDM) relates to the "Resources" in the above ontology. It is imperative that you apply a MDM strategy to your enterprise resource domain objects to avoid inconsistencies and multiple versions of the truth.

I hope this ontology makes my viewpoint on business process driven SOA clear to you. Feel free to comment on this model, and also check out the six figures in JJD’s ontology for models showing different perspectives of resource lifecycles & business events, BPEL, BPMN and human tasks.

See also this related post.

Thursday, June 14, 2007

What is WS-Splat anyway?

I just briefly gave an overview of the ten WS-* standards supported by WCF at my talk at NNUG a couple of weeks ago, as there are way too many topics there to cover in just one session. The ten supported standards are:
  • WS-Security
  • WS-Trust
  • WS-SecureConversation
  • WS-Policy
  • WS-SecurityPolicy
  • WS-Addressing
  • WS-ReliableMessaging
  • WS-AtomicTransaction
  • WS-Coordination
  • WS-MetadataExchange
Alas, Michele Leroux Bustamante has written an excellent introduction to all the different WS-* standards: Making Sense of all these Crazy Web Service Standards.

Definitely worth reading if you wonder whats the difference between WS-Security and WS-SecureConversation and other important issues. Then again, who wonders about such things...

Wednesday, May 30, 2007

WCF: Security Architecture and Claims

At my WCF talk at NNUG last night, I didn't have the time to go into the security architecture of WCF in general or into identity model details such as STS, tokens, policies and claims.

To get an overview of these aspects, I recommend reading "The holy grail of Enterprise SOA security" by Matias Woloski.

To learn more about how to actually build an authorization system based on claims, you should read "Building a Claims-Based Security Model in WCF" part 1 and part 2 by Michele Leroux Bustamente.

[UPDATE] Read the Digital Identity for .NET Applications whitepaper by David Chappell to get a good overview of the involved technology.