Reputation: 115
There is VS solution with 2 projects: mvc 3 web application and STS. When user navigate to a page for the first time he is redirected STS login page, authenticating there and returning back. Everything working good. Now need to change flow.
Users are authenticated when accessing the third party SSO application. When a user attempts to access web application through SSO, the SSO application delivers an access token to the web application via HTTP(s) request. This token, appended to the web application’s launch URL, is then returned by application back to SSO. After getting the access token, user data is delivered to the web application from SSO in XML format (including user ID, name, role), which web application should incorporate, parse to grant the user access.
The following is the request flow: 1) User navigates to the SSO login page and login there. 2) User is given a link to web application and clicks it. SSO creates an access token and redirects the access request to the web application's landing page (with the access token appended). 3) Web application returns the token to SSO (and parses the access token if needed). 4) SSO receives the access token, retrieves the associated user data (id, name, role), and returns an XML response (with id, user name, role) to the web application. 5) Web application establishing identity and authorize pages according claims taken from roles in the XML file.
How to do the last step 5? What class/method can be used to parse user name and role information to establishing identity based on user name, role in a way as it was after STS authentication?
Upvotes: 1
Views: 841
Reputation: 33306
From within your Web Application you will have to implement a ClaimsAuthenticationManager and a ClaimsAuthorisationManager. Something along the lines of this but your Claims will come from the token returned from your STS:
public class ClaimsTransformationModule : ClaimsAuthenticationManager
{
public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
{
if (!incomingPrincipal.Identity.IsAuthenticated)
{
return base.Authenticate(resourceName, incomingPrincipal);
}
return CreateApplicationPrincipal(incomingPrincipal.Identity.Name);
}
private ClaimsPrincipal CreateApplicationPrincipal(string userName)
{
var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, userName));
claims.Add(new Claim(ClaimTypes.GivenName, userName));
// add roles
var roles = Roles.GetRolesForUser(userName).ToList();
roles.ForEach(
r => claims.Add(new Claim(ClaimTypes.Role, r)));
return new ClaimsPrincipal(new ClaimsIdentity(claims, "Custom"));
}
}
public class CustomAuthorisationManager : ClaimsAuthorizationManager
{
public override bool CheckAccess(AuthorizationContext context)
{
string resource = context.Resource.First().Value;
string action = context.Action.First().Value;
if (action == "Edit" && resource == "User")
{
bool isAdmin = context.Principal.HasClaim(ClaimTypes.Role, "Admin");
return isAdmin;
}
return false;
}
}
You will have to add the configuration settings to your web.config for the
<configuration>
<configSections>
..
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
..
You can use claims token to store the claims in to save hitting your db everytime.
This article is very good and explains it all from start to finish:
Upvotes: 1