Configuration
The configuration showed on the following figure is a sample of how you can set the Forms Authentication attributes with security in mind. You should follow these hints for SSO Forms Auth. First of all, you should have the same settings (see forms element attributes) that are listed below on every site that you want to adhere to SSO.·Name·Protection·PathThe machineKey element might be configured on the machine.config file or on every web.config application file. In the first scenario, you may have the encryption key set to something like this (this is the default setting, albeit useless for this scenario):
<machineKey validationKey="AutoGenerate,IsolateApps" decryptionKey= "AutoGenerate,IsolateApps" validation="SHA1"/> |
The "IsolateApps" means that a different key will be AutoGenerated for *each* application. You can either remove the isolateApps option (for apps on the same machine) or insert a specific key value for it to use (for apps on different boxes). This last option is the one that is used on following the config sample.
<configuration>
<system.web>
<authentication mode="Forms">
<forms loginUrl="Secure\login.aspx" protection="All" requireSSL="true" timeout="10" name="FormsAuthCookie" path="/FormsAuth" slidingExpiration="true" />
</authentication> <!-- The virtual directory root folder contains general pages.Unauthenticated users can view them and they do not need to be secured with SSL. --><authorization><allow users="*" /> <!-- Allow all users --></authorization>
<machineKey validationKey="C50B…CABE" decryptionKey= "8A9BE8FD67AF6979E7D20198CFEA50DD3D3799C77AF2B72F" validation="SHA1"/> </system.web> <!-- The restricted folder is for authenticated and SSL access only. All pages on the Secure subfolder will be under SSL access. --><location path="Secure" >
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</location>
</configuration> |
Note: Check ouy the path attribute. This should be aligned with the app name. If you want to have SSO on every app, just leave the default value "/".
Principal Creation
After gathering the user credentials you will perform the authentication process and after that you will retrieve the user roles if you want to use the .NET role authorization pattern. This implies the creation of an Identity and a Principal object that will contain this data. So on the login page server side and after the auth process you will get the Forms ticket and save there your roles info and may be any other user profile related data (beware of size constrains, less than 4KB).
// Do auth with your preferred auth methodWindowsIdentity identity = WinAccessHelper.LogonUser( UserId, Password ); // Add rolesstring[] roles = WinAccessHelper.Roles( new WindowsPrincipal( identity ) );HttpCookie cookie = FormsAuthentication.GetAuthCookie( UserId.Text, false );FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value); // Store roles inside the Forms cookie.FormsAuthenticationTicket newticket = new FormsAuthenticationTicket(ticket.Version,ticket.Name,ticket.IssueDate,ticket.Expiration,ticket.IsPersistent,String.Join( "|", roles),ticket.CookiePath); cookie.Value = FormsAuthentication.Encrypt(newticket);Context.Response.Cookies.Set(cookie);Response.Redirect( FormsAuthentication.GetRedirectUrl( newticket.Name, newticket.IsPersistent ) );// For different domains, should use the cookie domain//HttpCookie formsCookie = FormsAuthentication.GetAuthCookie( UserId.Text, false );//formsCookie.Domain = "localhost.com";//Response.AppendCookie( formsCookie );//Response.Redirect( FormsAuthentication.GetRedirectUrl( UserId.Text, false ) );//FormsAuthentication.RedirectFromLoginPage( UserId.Text, false ); |
Principal Retrieving
On each AuthenticateRequest event of every SSO “federated” site you may retrieve your saved user info and create your Principal object and load them onto the User object of the current HttpContext instance. This is accomplished on the following figure.
protected void Application_AuthenticateRequest(Object sender, EventArgs e){if (Context.Request.IsAuthenticated)
{// retrieve user's identity from httpcontext user FormsIdentity ident = (FormsIdentity)Context.User.Identity;
// retrieve roles from the authentication ticket userdata field
string[] arrRoles = ident.Ticket.UserData.Split(new char[] {'|'}); // create principal and attach to user Context.User = new System.Security.Principal.GenericPrincipal(ident, arrRoles);}} |
No comments:
Post a Comment