Compartilhar via


RIA Services and Windows Identity Foundation – Claims enabling a RIA application

Recently a Customer asked me if an application using RIA Services could use WIF. I’m fairly new to RIA Services so I didn’t know the answer right away, however I suspected the integration should not be too hard, so I spend a couple of days spiking a solution.

The good news: it just works!     

What I did:

I took one of the samples available from the RIA Services website (HRApp, you can download it here: https://code.msdn.microsoft.com/RiaServices, more specifically: https://code.msdn.microsoft.com/RiaServices/Release/ProjectReleases.aspx?ReleaseId=2387 )

After installing and verifying everything worked, I “claims enabled” it by running “FedUtil.exe”. I configured it to point to Adatum Issuer (exactly the same you can download from the Guide CodePlex site: https://claimsid.codeplex.com).

As expected, FedUtil changed a few setting in the app config file to enable claims: WIF modules were registered and the relationship with Adatum Issuer was established:

clip_image001

clip_image002

I then ran the application again and I was gladly surprised to be first redirected to the Issuer for authentication:

clip_image003

If you have installed the Guide samples, you are probably familiar with this screen and you know that it will issue a set of claims for a user “Mary” that includes 2 roles “Orders approvers”, “Employees”. When I click on “continue button”, claims are issued and sent to the RIA application where now I’m authenticated and recognized:

clip_image004

If you break into the application (server side) and inspect the User object from the HttpContext you’ll notice there’s a “ClaimsIdentity” and you have access of course to the claims collection, etc. That is part of the “magic” performed by WIF modules:

clip_image005

On the Silverlight side, you can see that now the User object in the RiaContext also reflects the content obtained in the server side. This is thanks to some of the magic wiring RIA Services does for us:

clip_image006

RIA Services out of the box implementations rely on ASP.NET infrastructure. I didn’t want to change the sample app too much, so I created a very simple RoleProvider that would simply resolve GetRolesForUser through the ClaimsIdentity. Here’s the (only) method that I implemented from the RoleProvider base class:

public override string[] GetRolesForUser(string username)
{
    var id = HttpContext.Current.User.Identity as IClaimsIdentity;
    return (from c in id.Claims
            where c.ClaimType == ClaimTypes.Role
            select c.Value).ToArray();
}

 

Roles are enabled in the web.config:

<roleManager enabled="true" defaultProvider="GenevaRoles">
<providers>
<add name="GenevaRoles" type="HRApp.Web.GenevaRolesProvider, HRApp.Web"/>
</providers>
</roleManager>

 

Of course, Roles are Claims, but not all Claims are roles. You could extend the RIA User object to hold whatever other information you want. So you could end up having any other profile data in the user object that comes from a Claim (e.g. the “Cost Center” claim that our Issuer gives us).

Many thanks to Erwin for his help.

Comments

  • Anonymous
    October 28, 2009
    Hi, I downloaded HRApp, and ran "Federation Utility Tool" from VS 2008's tool meuu, my web.config did not change. I tried to manually copying down the parts you showed to my web.config, it is not working either. The pasted image looks a bit blurry to me, do you mind publish the whole project or web.config? I have not yet gone through the guide examples in detail, but what would happen if I register new user from HRApp? Don't you need to implement some service class code at the provider end? I am trying to build a claim-awared PRISM application. My idea is instead of redirecting to STS's login HTML page, the prism app would load an xap to do validation/registration against a membership store at the STS site on demand. Is it doable? My understanding is in the passive federation model, the web server redirects you to sign in page, and get back the control to the website. In my case, the redirection will be triggered by a PRISM shell or a navigation application upon clicking login button to run an xap file on demand, and it will need to return to the silverlight app with its state intact.  Can it be done? Thanks. Reggie

  • Anonymous
    October 28, 2009
    The comment has been removed

  • Anonymous
    December 04, 2009
    Good article, Eugenio. Would you be able to publish solution code, please?

  • Anonymous
    December 04, 2009
    Thanks!! There's not much code besides what I shared in the post. Most of it is genrated code (the STS). The only added code is the roles provider with this single method: public override string[] GetRolesForUser(string username) {    var id = HttpContext.Current.User.Identity as IClaimsIdentity;    return (from c in id.Claims            where c.ClaimType == ClaimTypes.Role            select c.Value).ToArray(); }

  • Anonymous
    December 18, 2009
    You say above: 'If you break into the application (server side) and inspect the User object from the HttpContext you’ll notice there’s a “ClaimsIdentity” and you have access of course to the claims collection, etc. That is part of the “magic” performed by WIF modules'. However, when I run a similar scenario to the above, but without Ria Services (Raw Silverlight 3 with a passive STS), when I check Thread.Principle.Identity it says IsAuthenticated=false and none of my claims are in the Claims collection. I've traced the whole process through fiddler and I can see that the STS does issue the claims (I turned all the encryption off to verify), and these claims are passed to the web-server and stored in a cookie, which my WCF request is then passing back to the server. However, when I get into the WCF operation, although the type of Thread.Principal.Identity is IClaimsIdentity, nothing is filled into this object. Is RIA services maybe doing something special to fill these values in that I'm missing?

  • Anonymous
    December 18, 2009
    No, RIA Services uses HttpContext.Current.User. It doesn't do anything special with it. Who is hosting the web service?si the same app that hosts the web site?

  • Anonymous
    February 09, 2010
    The example worked for me Thanks, but i would like to logoff and re-login to my app then How do i redirect to the STS provider when i click the login link from Silverlight app,  

  • Anonymous
    October 06, 2010
    Eugenio, can Silverlight be active ou passive?