#ClientApplicationServices
Explore tagged Tumblr posts
Text
Convert FormsIdentity To ClientFormsIdentity
Background If you have been using Client Application Settings (CAS), like me, you are well aware that it is a great framework. But like anything else, it has a few limitations. In this case we are referring to an issue that you may encounter when working in a Single Sign-On (SSO) environment.
The issue materializes when you have an authenticated user that requests a page on your site where your Profile information is provided via CAS. The reason this is an issue is that ASP.NET, when using Forms authentication, will populate the HttpContext.Current.User.Identity property with a FormsIdentity. However, with CAS you are going to need a ClientFormsIdentity. You are going to need to craft some magic to get that FormsIdentity into a ClientFormsIdentity and attached to Thread.CurrentPrincipal.
Scenario So, lets set some assumptions here for what we are working with:
You have written an ASP.NET web service which uses Forms authentication
Your authentication is provided by an SSO service, which also has CAS enabled
An authenticated client calls your service.
Our task is to get the User's Profile (settings), which are provided by CAS, to be populated.
The Issue CAS Settings (Profile) properties are associated with the current Thread. The problem with this is that ASP.NET does not impersonate the logged in user. This is also an older feature of .NET which will require your Application Pool in IIS to be configured to use the Classic pipeline - which we are not going to do.
For some applications this may not even be viable, such as WCF DataServices which requires the integrated pipeline. So, what we need to do is take our authenticated FormsIdentity, turn it into a ClientFormsIdentity and attach it to Thread.CurrentPrincipal.
An additional note is that the CAS settings will not load unless the current Thread's principal derrives from the ClientFormsIdentity, which is the identity type set when you use CAS's Membership.ValidateUser. This method sets the Thread.CurrentPrincipal property.
The Solution To solve this, we will need to take our HttpContext.Current.User.Identity and snag the authentication cookies from it.
var identity = HttpContext.Current.User.Identity as FormsIdentity; CookieContainer container = new CookieContainer(); foreach (String key in HttpContext.Current.Request.Cookies) { var cookie = HttpContext.Current.Request.Cookies[key]; container.Add(new Cookie(cookie.Name, cookie.Value, cookie.Path, String.Empty)); }
This simply creates a new CookieContainer which we can use with CAS. After we have this, it is as easy as simply creating our new identity and silently re-authenticating it.
ClientFormsIdentity ident = new ClientFormsIdentity(string.Empty, string.Empty, Membership.Provider, "ClientForms", true, container);
Thread.CurrentPrincipal = new ClientRolePrincipal(ident); ident.RevalidateUser();
The beauty with CAS is that even though we do not have the username or password, it will use the authentication cookies that were given to us to re-validate them. After the Thread.CurrentPrincipal value is set, we will be able to access the Properties from our CAS settings provider.
2 notes
·
View notes
Text
Resolving NullReferenceException with ClientApplicationServices / ProfileService
If you have been (or trying to) work with Client Application Services, you may have chased this issue like I did this morning.
The Setup You are working with Client Application Services, specifically the Profile Service. You have either added a new profile property or you are just trying to get synched up for the first time. You select Load Web Settings, you enter a valid username/password, it waits for a second and then you get this....
The Solution The real culprit, in my opinnion, is a bug in the profile service which should at least fail a bit more gracefully. You can resolve the error by updating (or adding) the following configuration section to your web.config ...
System.Web.Extensions/Scripting/webServices/profileService
Upon further inspection...
By default, no profile properties are available. To make a profile property available to a client application, add the property name to the readAccessProperties attribute of the profileService element. To enable a client application to update a profile property value, add the property name to the writeAccessProperties attribute.
So, armed with knowledge we can now add a coma delimited list of properties in the readAccessProperties attribute of the profileService configuration entry.
<profileService enabled="true" readAccessProperties="FirstName,LastName,EmailAddress" />
2 notes
·
View notes