SecurityTokenService 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
抽象基底類別,定義安全性權杖服務 (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 類別。 在您的自定義類別中,您至少必須覆寫 GetScope 和 GetOutputClaimsIdentity 方法。 使用這些覆寫,使用 類別中定義之所有其他方法的預設實作所建立的 STS 能夠發出安全性令牌,以回應 RST) (安全性令牌要求。 也就是說,實作 WS-Trust 規格中定義的問題系結。 這個系結是在方法中實作 Issue 。 如果遇到對應至其中一個系結的 RST,則不會在預設案例中實作其他 WS-Trust 系結 (更新、取消和驗證) ,而且如果遇到對應至其中一個系結的 RST,則會將適當的錯誤傳回給呼叫端。 當然,您可以覆寫適當的方法, Renew (、 Cancel和 Validate) ,以在您的 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 定義的許多其他方法都是從這個方法呼叫,包括 GetScope 和 GetOutputClaimsIdentity 方法。 您不需要覆寫這個方法,但瞭解所實作的令牌要求管線可能會很有説明。
STS 會透過 類別進行 SecurityTokenServiceConfiguration 設定。
給實施者的注意事項
您必須同時覆寫 GetScope(ClaimsPrincipal, RequestSecurityToken) 和 GetOutputClaimsIdentity(ClaimsPrincipal, RequestSecurityToken, Scope) 方法。
建構函式
SecurityTokenService(SecurityTokenServiceConfiguration) |
使用指定的組態設定,從衍生類別呼叫以初始化 SecurityTokenService 類別。 |
屬性
Principal |
取得或設定與目前執行個體相關聯的主體。 |
Request |
取得或設定與目前執行個體相關聯的安全性權杖要求 (RST)。 |
Scope |
取得或設定與目前執行個體相關聯的範圍。 |
SecurityTokenDescriptor |
取得或設定與目前執行個體相關聯的 SecurityTokenDescriptor。 |
SecurityTokenServiceConfiguration |
取得擁有者組態執行個體。 |