首先我们来说说STS(Security Token Service)的最简生命周期,当然这是要基于WIF(Windows Identity Foundation)框架的。
一. 分析传入数据的可用性,并创建SignInRequestMessage
WSFederationMessage提供CreateFromUri以及CreateFromNameValueCollection等简单的创建入口(本例使用CreateFromUri)
二. 通过对SignInRequestMessage的解析以及确认,生成SignInResponseMessage
1.创建SecurityTokenServiceConfiguration以驱动自定义SecurityTokenService
a)自定义的SecurityTokenService需要对以下的内容进行定义:
* ClaimsIdentity发布的内容(Claims的ClaimsType和Value需要搭建STS人自己定义)
* Scope的定义
b) Scope无非是对请求STS端应用以及其他的Policy进行定义,其中SignedCertificate必须要进行定义。
2.创建WSFederationSerializer以对SignInRequestMessage进行处理,并序列化SignInResponseMessage
3.验证SignInRequestMessage 内容的有效性(如果STS使用的是Windows 身份验证,可以忽略此项)
4. 获取验证过的自定义的Identity(或者系统Identity),结合SignInRequestMessage,通过自定义SecurityTokenService进行发布(Issue),获取RequestSecurityTokenResponse
5. 获取最终的SignInResponseMessage
声明周期即以上的部分,这是最简单的方式,其余的需要进行自定义的部分,可以在这简单的实例基础上进行添加。
以下是代码部分
一. 自定义Security Token Service
public class CustomSTS : SecurityTokenService { private SigningCredentials _signingCreds; private EncryptingCredentials _encryptingCreds; public CustomSTS(SecurityTokenServiceConfiguration configuration) :base(configuration) { _signingCreds = new X509SigningCredentials(new X509Certificate2(@"C:\Users\Administrator\Desktop\ForNewSTS.pfx","1qaz2wsxE")); _encryptingCreds = new X509EncryptingCredentials(new X509Certificate2(@"C:\Users\Administrator\Desktop\ForNewSTS.pfx", "1qaz2wsxE")); } protected override Microsoft.IdentityModel.Claims.IClaimsIdentity GetOutputClaimsIdentity(Microsoft.IdentityModel.Claims.IClaimsPrincipal principal, Microsoft.IdentityModel.Protocols.WSTrust.RequestSecurityToken request, Scope scope) { ClaimsIdentity outputIdentity = new ClaimsIdentity(); outputIdentity.Claims.Add(new Claim("http://test.com/c/c","/create")); return outputIdentity; } protected override Scope GetScope(Microsoft.IdentityModel.Claims.IClaimsPrincipal principal, Microsoft.IdentityModel.Protocols.WSTrust.RequestSecurityToken request) { Scope sc = new Scope(request.AppliesTo.Uri.AbsoluteUri, _signingCreds); sc.TokenEncryptionRequired = false; sc.ReplyToAddress = request.ReplyTo; return sc; } }
二. 生成SignInResponseMessage的简易流程
private SignInResponseMessage ProcessSignInRequest(SignInRequestMessage requestMessage) { // Ensure that the requestMessage has the required wtrealm parameter if (String.IsNullOrEmpty(requestMessage.Realm)) { throw new InvalidOperationException("Missing realm"); } //set the SecurityTokenService Configuration Name, this name should be unique. SecurityTokenServiceConfiguration stsconfig = new SecurityTokenServiceConfiguration("PassiveFlowSTS"); // Create our STS backend SecurityTokenService sts = new CustomSTS(stsconfig); // Create the WS-Federation serializer to process the request and create the response WSFederationSerializer federationSerializer = new WSFederationSerializer(); // Create RST from the request RequestSecurityToken request = federationSerializer.CreateRequest(requestMessage, new WSTrustSerializationContext()); // Get RSTR from our STS backend RequestSecurityTokenResponse response = sts.Issue((IClaimsPrincipal)GenericAPrincipal(), request); // Create Response message from the RSTR return new SignInResponseMessage(new Uri(response.ReplyTo), federationSerializer.GetResponseAsString(response, new WSTrustSerializationContext())); } public IClaimsPrincipal GenericAPrincipal() { IClaimsIdentity localIdentity = new ClaimsIdentity("testFederation", "http://xxx.com/c/test", "somebody in STS"); List<IClaimsIdentity> list = new List<IClaimsIdentity>(); list.Add(localIdentity); ClaimsPrincipal p = new ClaimsPrincipal(list); return p; }