VS解决方案有2个项目:mvc 3 Web应用程序和STS。 当用户第一次导航到页面时,他被重定向到STS登录页面,在那里进行身份验证并返回。 一切都很好。 现在需要改变流程。
访问第三方SSO应用程序时,用户已通过身份验证。 当用户尝试通过SSO访问Web应用程序时,SSO应用程序通过HTTP(s)请求向Web应用程序提供访问令牌。然后,应用程序将此标记附加到Web应用程序的启动URL,并返回给SSO。 获取访问令牌后,用户数据将以SSO格式(包括用户ID,名称,角色)从SSO传递到Web应用程序,Web应用程序应该包含该解析,解析以授予用户访问权限。
以下是请求流程: 1)用户导航到SSO登录页面并登录。 2)为用户提供指向Web应用程序的链接并单击它。 SSO创建访问令牌并将访问请求重定向到Web应用程序的登录页面(附加访问令牌)。 3)Web应用程序将令牌返回给SSO(并在需要时解析访问令牌)。 4)SSO接收访问令牌,检索关联的用户数据(id,名称,角色),并向Web应用程序返回XML响应(具有id,用户名,角色)。 5)Web应用程序根据从XML文件中的角色获取的声明来建立身份和授权页面。
如何进行最后一步5? 可以使用什么类/方法来解析用户名和角色信息,以便根据用户名,角色以及STS身份验证后的方式建立身份?
答案 0 :(得分:1)
在Web应用程序中,您必须实现ClaimsAuthenticationManager和ClaimsAuthorisationManager。根据这一点,你的索赔将来自你的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;
}
}
您必须将配置设置添加到
的web.config中<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"/>
..
您可以使用声明令牌存储声明,以便每次都保存命中数据库。
这篇文章非常好,从头到尾解释了所有内容: