SecurityTokenService 類別

定義

抽象基底類別,定義安全性權杖服務 (STS) 的屬性和方法。

public ref class SecurityTokenService abstract
public abstract class SecurityTokenService
type SecurityTokenService = class
Public MustInherit Class SecurityTokenService
繼承
SecurityTokenService

範例

主題中使用的 SecurityTokenService 程式代碼範例取自 Custom Token 範例。 此範例提供自定義類別,可讓您處理簡單的 Web 令牌 (SWT) ,並包含能夠提供 SWT 令牌的被動 STS 實作。 如需如何實作作用中 STS 的範例,您可以查看 Federation Metadata 範例。 如需這些範例和其他可供 WIF 使用之範例以及下載位置的相關信息,請參閱 WIF 程式代碼範例索引。 下列程式代碼示範使用 SecurityTokenService 類別實作被動 STS。

using System;
using System.IdentityModel;
using System.IdentityModel.Configuration;
using System.IdentityModel.Protocols.WSTrust;
using System.IdentityModel.Tokens;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;

namespace PassiveSTS
{
    /// <summary>
    /// Overrides the SecurityTokenService class to provide
    /// the relying party related information, such as encryption credentials to encrypt the issued
    /// token, signing credentials to sign the issued token, claims that the STS wants to issue for a 
    /// certain token request, as well as the claim types that this STS is capable
    /// of issuing.
    /// </summary>
    public class CustomSecurityTokenService : SecurityTokenService
    {
        // Certificate Constants
        private const string SIGNING_CERTIFICATE_NAME = "CN=localhost";
        private const string ENCRYPTING_CERTIFICATE_NAME = "CN=localhost";

        private SigningCredentials _signingCreds;
        private EncryptingCredentials _encryptingCreds;
        // Used for validating applies to address, set to URI used in RP app of application, could also have been done via config
        private string _addressExpected = "http://localhost:19851/";
        public CustomSecurityTokenService(SecurityTokenServiceConfiguration configuration)
            : base(configuration)
        {
            // Setup the certificate our STS is going to use to sign the issued tokens
            _signingCreds = new X509SigningCredentials(CertificateUtil.GetCertificate(StoreName.My, StoreLocation.LocalMachine, SIGNING_CERTIFICATE_NAME));

            // Note: In this sample app only a si   ngle RP identity is shown, which is localhost, and the certificate of that RP is 
            // populated as _encryptingCreds
            // If you have multiple RPs for the STS you would select the certificate that is specific to 
            // the RP that requests the token and then use that for _encryptingCreds
            _encryptingCreds = new X509EncryptingCredentials(CertificateUtil.GetCertificate(StoreName.My, StoreLocation.LocalMachine, ENCRYPTING_CERTIFICATE_NAME));
        }

        /// <summary>
        /// This method returns the configuration for the token issuance request. The configuration
        /// is represented by the Scope class. In our case, we are only capable of issuing a token to a
        /// single RP identity represented by the _encryptingCreds field.
        /// </summary>
        /// <param name="principal">The caller's principal</param>
        /// <param name="request">The incoming RST</param>
        /// <returns></returns>
        protected override Scope GetScope(ClaimsPrincipal principal, RequestSecurityToken request)
        {
            // Validate the AppliesTo address
            ValidateAppliesTo( request.AppliesTo );

            // Create the scope using the request AppliesTo address and the RP identity
            Scope scope = new Scope( request.AppliesTo.Uri.AbsoluteUri, _signingCreds );

            if (Uri.IsWellFormedUriString(request.ReplyTo, UriKind.Absolute))
            {
                if (request.AppliesTo.Uri.Host != new Uri(request.ReplyTo).Host)
                    scope.ReplyToAddress = request.AppliesTo.Uri.AbsoluteUri;
                else
                    scope.ReplyToAddress = request.ReplyTo;
            }
            else
            {
                Uri resultUri = null;
                if (Uri.TryCreate(request.AppliesTo.Uri, request.ReplyTo, out resultUri))
                    scope.ReplyToAddress = resultUri.AbsoluteUri;
                else
                    scope.ReplyToAddress = request.AppliesTo.Uri.ToString() ;
            }

            // Note: In this sample app only a single RP identity is shown, which is localhost, and the certificate of that RP is 
            // populated as _encryptingCreds
            // If you have multiple RPs for the STS you would select the certificate that is specific to 
            // the RP that requests the token and then use that for _encryptingCreds
            scope.EncryptingCredentials = _encryptingCreds;

            return scope;
        }
        /// <summary>
        /// This method returns the content of the issued token. The content is represented as a set of
        /// IClaimIdentity intances, each instance corresponds to a single issued token. Currently, the Windows Identity Foundation only
        /// supports a single token issuance, so the returned collection must always contain only a single instance.
        /// </summary>
        /// <param name="scope">The scope that was previously returned by GetScope method</param>
        /// <param name="principal">The caller's principal</param>
        /// <param name="request">The incoming RST, we don't use this in our implementation</param>
        /// <returns></returns>
        protected override ClaimsIdentity GetOutputClaimsIdentity( ClaimsPrincipal principal, RequestSecurityToken request, Scope scope )
        {
            //
            // Return a default claim set which contains a custom decision claim
            // Here you can actually examine the user by looking at the IClaimsPrincipal and 
            // return the right decision based on that. 
            //
            ClaimsIdentity outgoingIdentity = new ClaimsIdentity();
            outgoingIdentity.AddClaims(principal.Claims);

            return outgoingIdentity;
        }
        /// <summary>
        /// Validates the appliesTo and throws an exception if the appliesTo is null or appliesTo contains some unexpected address.
        /// </summary>
        /// <param name="appliesTo">The AppliesTo parameter in the request that came in (RST)</param>
        /// <returns></returns>
        void ValidateAppliesTo(EndpointReference appliesTo)
        {
            if (appliesTo == null)
            {
                throw new InvalidRequestException("The appliesTo is null.");
            }

            if (!appliesTo.Uri.Equals(new Uri(_addressExpected)))
            {
                throw new InvalidRequestException(String.Format("The relying party address is not valid. Expected value is {0}, the actual value is {1}.", _addressExpected, appliesTo.Uri.AbsoluteUri));
            }
        }

    }
}

下列程式代碼示範如何叫用自定義被動 STS,以從 檔案中的程式代碼後default.aspx.cs置呼叫 FederatedPassiveSecurityTokenServiceOperations.ProcessRequest(HttpRequest, ClaimsPrincipal, SecurityTokenService, HttpResponse) 方法來處理 WS-Federation 要求。

using System;
using System.IdentityModel.Services;
using System.Security.Claims;

namespace PassiveSTS
{
    public partial class _Default : System.Web.UI.Page
    {
        /// <summary>
        /// We perform the WS-Federation Passive Protocol processing in this method. 
        /// </summary>
        protected void Page_PreRender( object sender, EventArgs e ) 
        {
            FederatedPassiveSecurityTokenServiceOperations.ProcessRequest( Request, User as ClaimsPrincipal, CustomSecurityTokenServiceConfiguration.Current.CreateSecurityTokenService(), Response );
        }
    }
}

備註

若要建立 STS,您必須衍生自 SecurityTokenService 類別。 在您的自定義類別中,您至少必須覆寫 GetScopeGetOutputClaimsIdentity 方法。 使用這些覆寫,使用 類別中定義之所有其他方法的預設實作所建立的 STS 能夠發出安全性令牌,以回應 RST) (安全性令牌要求。 也就是說,實作 WS-Trust 規格中定義的問題系結。 這個系結是在方法中實作 Issue 。 如果遇到對應至其中一個系結的 RST,則不會在預設案例中實作其他 WS-Trust 系結 (更新、取消和驗證) ,而且如果遇到對應至其中一個系結的 RST,則會將適當的錯誤傳回給呼叫端。 當然,您可以覆寫適當的方法, Renew (、 CancelValidate) ,以在您的 STS 中實作這些系結。

重要

實作生產環境就緒的 STS 需要仔細規劃和大量資源,以降低公開這類服務時固有的潛在安全性風險。 大部分使用 Windows Identity Foundation (WIF) 的開發人員都會開發將身分識別管理外包給 STS 的應用程式,而不是開發 STS 本身。 WIF 提供 Visual Studio 延伸模組 Visual Studio 2012 的身分識別和存取工具,以協助開發人員在開發環境中測試解決方案。 此工具包含 STS , LocalSTS您可以設定來為開發的應用程式提供特定宣告。 如需身分識別和存取工具的詳細資訊,請參閱 Visual Studio 2012的身分識別和存取工具。 在某些情況下, LocalSTS 可能無法提供適當測試應用程式所需的功能;例如,在涉及開發自定義令牌處理程式以供應用程式使用的案例中。 在這些情況下,您可以衍生自 SecurityTokenService 來建立一或多個可在開發環境中部署的簡單 STS,並可用來在應用程式中測試這類功能。 本節的其餘部分著重於 類別所 SecurityTokenService 公開的方法,可讓您實作簡單的 STS 並擴充令牌發行管線。

下列清單提供開發人員在測試或開發環境中使用之主要重要性方法的簡短概觀。

  • GetScope 方法 這個方法會傳 Scope 回 物件,其中包含 RP 的相關信息。 此物件會在令牌發行管線的其餘部分使用,並包含簽署和加密用於響應的認證相關信息,以及 AppliesTo 視需要) 位址的 和 ReplyTo (。 您必須覆寫這個方法。

  • GetOutputClaimsIdentity 方法 這個方法會傳 ClaimsIdentity 回 物件,其中包含要傳回至 RP 的宣告。 您必須覆寫這個方法。

  • Issue 方法 此方法會實作令牌要求管線,此管線會處理傳入的安全性令牌要求 (RST) ,並將回應 (RSTR) 傳回給呼叫端,其中包含可用來向 RP 進行驗證的令牌。 類別中 SecurityTokenService 定義的許多其他方法都是從這個方法呼叫,包括 GetScopeGetOutputClaimsIdentity 方法。 您不需要覆寫這個方法,但瞭解所實作的令牌要求管線可能會很有説明。

STS 會透過 類別進行 SecurityTokenServiceConfiguration 設定。

給實施者的注意事項

您必須同時覆寫 GetScope(ClaimsPrincipal, RequestSecurityToken)GetOutputClaimsIdentity(ClaimsPrincipal, RequestSecurityToken, Scope) 方法。

建構函式

SecurityTokenService(SecurityTokenServiceConfiguration)

使用指定的組態設定,從衍生類別呼叫以初始化 SecurityTokenService 類別。

屬性

Principal

取得或設定與目前執行個體相關聯的主體。

Request

取得或設定與目前執行個體相關聯的安全性權杖要求 (RST)。

Scope

取得或設定與目前執行個體相關聯的範圍。

SecurityTokenDescriptor

取得或設定與目前執行個體相關聯的 SecurityTokenDescriptor

SecurityTokenServiceConfiguration

取得擁有者組態執行個體。

方法

BeginCancel(ClaimsPrincipal, RequestSecurityToken, AsyncCallback, Object)

在衍生類別中覆寫時,開始非同步 WS-Trust 取消要求。

BeginGetOutputClaimsIdentity(ClaimsPrincipal, RequestSecurityToken, Scope, AsyncCallback, Object)

在衍生類別中覆寫時,開始非同步呼叫 GetOutputClaimsIdentity(ClaimsPrincipal, RequestSecurityToken, Scope) 方法。

BeginGetScope(ClaimsPrincipal, RequestSecurityToken, AsyncCallback, Object)

在衍生類別中覆寫時,開始 GetScope(ClaimsPrincipal, RequestSecurityToken) 方法的非同步呼叫。

BeginIssue(ClaimsPrincipal, RequestSecurityToken, AsyncCallback, Object)

在衍生類別中覆寫時,開始非同步 WS-Trust 發行要求。

BeginRenew(ClaimsPrincipal, RequestSecurityToken, AsyncCallback, Object)

在衍生類別中覆寫時,開始非同步 WS-Trust 更新要求。

BeginValidate(ClaimsPrincipal, RequestSecurityToken, AsyncCallback, Object)

在衍生類別中覆寫時,開始非同步 WS-Trust 驗證要求。

Cancel(ClaimsPrincipal, RequestSecurityToken)

在衍生類別中覆寫時,處理 WS-Trust 取消要求。

CreateSecurityTokenDescriptor(RequestSecurityToken, Scope)

建立 SecurityTokenDescriptor 的執行個體。

EndCancel(IAsyncResult)

在衍生類別中覆寫時,完成非同步 WS-Trust 取消要求。

EndGetOutputClaimsIdentity(IAsyncResult)

在衍生類別中覆寫時,完成非同步呼叫 BeginGetOutputClaimsIdentity(ClaimsPrincipal, RequestSecurityToken, Scope, AsyncCallback, Object) 方法。

EndGetScope(IAsyncResult)

在衍生類別中覆寫時,完成非同步呼叫 BeginGetScope(ClaimsPrincipal, RequestSecurityToken, AsyncCallback, Object) 方法。

EndIssue(IAsyncResult)

在衍生類別中覆寫時,完成非同步 WS-Trust 發行要求。

EndRenew(IAsyncResult)

在衍生類別中覆寫時,完成非同步 WS-Trust 更新要求。

EndValidate(IAsyncResult)

在衍生類別中覆寫時,完成非同步 WS-Trust 驗證要求。

Equals(Object)

判斷指定的物件是否等於目前的物件。

(繼承來源 Object)
GetHashCode()

做為預設雜湊函式。

(繼承來源 Object)
GetIssuerName()

取得安全性權杖服務 (STS) 的名稱。

GetOutputClaimsIdentity(ClaimsPrincipal, RequestSecurityToken, Scope)

在衍生類別中覆寫,這個方法會傳回包含在已發行權杖中的輸出主體集合。

GetProofToken(RequestSecurityToken, Scope)

取得要包含在回應 (RSTR) 的證明權杖。

GetRequestorProofEncryptingCredentials(RequestSecurityToken)

取得要求者的證明加密認證。

GetResponse(RequestSecurityToken, SecurityTokenDescriptor)

使用指定的要求 (RST) 和安全性權杖描述元,建立包含核發之權杖的回應 (RSTR)。

GetScope(ClaimsPrincipal, RequestSecurityToken)

取得 Scope 物件,其中包含與所指定的要求 (RST) 相關聯之信賴憑證者 (RP) 的相關資訊。 您必須在 SecurityTokenService 類別的實作中覆寫此方法。

GetSecurityTokenHandler(String)

取得適當的安全性權杖處理常式,以發出指定之類型的安全性權杖。

GetTokenLifetime(Lifetime)

取得已發行權杖的存留期。

GetType()

取得目前執行個體的 Type

(繼承來源 Object)
Issue(ClaimsPrincipal, RequestSecurityToken)

發行安全性權杖。

MemberwiseClone()

建立目前 Object 的淺層複製。

(繼承來源 Object)
Renew(ClaimsPrincipal, RequestSecurityToken)

在衍生類別中覆寫時,處理 WS-Trust 更新要求。

ToString()

傳回代表目前物件的字串。

(繼承來源 Object)
Validate(ClaimsPrincipal, RequestSecurityToken)

在衍生類別中覆寫時,處理 WS-Trust 驗證要求。

ValidateRequest(RequestSecurityToken)

驗證此執行個體封裝的安全性權杖要求 (RST)。

適用於

另請參閱