天天看點

簡單易懂的Security Token Service執行個體以及介紹

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