I have 2 web applications that both share the same main level domain as mentioned below so I can share cookies. Web.conifg in both the projects have same machine key and validation key. Since, I want to use Identity and NOT forms authenticaiton, I do not have an node in either of my web.config file. I am able to create the Auth cookie successully from SSO and can view the authorized pages in SSO but I am still redirected to SSO login when I try to access an authorized view in MVC project.
I have a startup.cs file in my SSO and MVC project like below:
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
// For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Enable the application to use a cookie to store information for the signed in user
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
ExpireTimeSpan = TimeSpan.FromMinutes(3),
LoginPath = new PathString("/Login"),
CookieName = "MyCookieName",
CookieDomain = ".domain.com"
});
app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
}
}
Below is the code I have so far in the SSO project under the AccountController.cs. I call the IdentitySignin function below on validating the user against the database which creates the cookie:
private void IdentitySignin(string userId, string name, string providerKey = null, bool isPersistent = false)
{
var claims = new List<Claim>();
// create *required* claims
claims.Add(new Claim(ClaimTypes.NameIdentifier, userId));
claims.Add(new Claim(ClaimTypes.Name, name));
var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
//get the expiry minutes from config or use the default value of 30 minutes
double expiryMinutes;
expiryMinutes = double.TryParse(ConfigurationManager.AppSettings["AuthCookieExpiryMinutes"], out expiryMinutes) ? expiryMinutes : 30;
// add to user here!
AuthenticationManager.SignIn(new AuthenticationProperties()
{
AllowRefresh = true,
IsPersistent = isPersistent,
ExpiresUtc = DateTime.UtcNow.AddMinutes(expiryMinutes),
IssuedUtc = DateTime.UtcNow
}, identity);
}
private void IdentitySignout()
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie, DefaultAuthenticationTypes.ExternalCookie);
}
private IAuthenticationManager AuthenticationManager
{
get
{
return HttpContext.GetOwinContext().Authentication;
}
}
private async Task<string> GetVerifiedUserIdAsync()
{
var result = await AuthenticationManager.AuthenticateAsync(
DefaultAuthenticationTypes.ApplicationCookie);
if (result != null && result.Identity != null
&& !String.IsNullOrEmpty(result.Identity.GetUserId()))
{
return result.Identity.GetUserId();
}
return null;
}
How to Implement Single Sign On in ASP.NET MVC? Implementing SSO in ASP.NET MVC is very simple. Below is the step by step approach to implement it. Open Visual Studio, create a blank solution (I always like to start off with a blank solution). Now add three empty ASP.NET MVC Web Applications ( SSO, WebApp1 & WebApp2) to the solution.
Just as an FYI, to share ASP.NET Identity Authentication between more than 1 application, make sure you have below things in EACH APP: SAME COOKIE NAME AND COOKIE DOMAIN in the Startup.cs Thanks for contributing an answer to Stack Overflow! Please be sure to answer the question. Provide details and share your research! But avoid …
This means that there was no single sign-on (SSO) between those applications. Our customer needed to: Present selected views (pages) of the new back-office system and reporting system inside an existing front-office application (through IFrames). Introduce a Single Sign-On mechanism to avoid repeat login when navigating between different systems.
To setup SSO, the project must be created with the authentication type as either individual account or identity platform. Additionally, as per standard Identity Framework convention, any methods/controllers that require the user to be signed in, require an [authorize] data annotation declared above.
Most likely, you haven't set a shared machine key. The auth cookie is encrypted, and unless both sites share the same machine key, one cannot decrypt what the other encrypted. Add the following to both project's Web.config:
<sytem.web>
...
<machineKey validation="HMACSHA256" validationKey="[validationKey]" decryptionKey="[decryptionKey]" compatibilityMode="Framework45" />
To generate the keys, in IIS, click on the server in the left pane, and then the Machine Key control panel item. Choose your validation method (above, I've used HMACSHA256). I don't recommend using the default of SHA1 as that's ridiculously easy to crack. Then, on the right "Actions" panel, click "Generate Keys". Copy the two text box values to the appropriate attributes of this config element, and make sure they are the same for all projects that need to share the auth cookie.
So, I figured out the reason why Single Sign On wasn't working between 2 MVC applications in-spite of both of them sharing the same machine and validation keys.
My SSO MVC application and the other MVC application were both using different version of OWIN and ASP.NET Identity DLLs. I used the Nuget to update the DLLS in one project but did not do the update in the other one.
I hope this helps someone who runs into this problem.
Just as an FYI, to share ASP.NET Identity Authentication between more than 1 application, make sure you have below things in EACH APP:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With