首先我們來說說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;
}