SecurityTokenService 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
定義安全令牌服務(STS)屬性與方法的抽象基底類別。
public ref class SecurityTokenService abstract
public abstract class SecurityTokenService
type SecurityTokenService = class
Public MustInherit Class SecurityTokenService
- 繼承
-
SecurityTokenService
範例
主題中使用 SecurityTokenService 的程式碼範例取自範例 Custom Token 。 本範例提供自訂類別,使簡單網路令牌(SWT)能夠處理,並包含一個被動 STS 實作,能服務 SWT 令牌。 關於如何實作主動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 來處理 WS-Federation 請求,方法是從檔案中FederatedPassiveSecurityTokenServiceOperations.ProcessRequest(HttpRequest, ClaimsPrincipal, SecurityTokenService, HttpResponse)程式碼中呼叫該default.aspx.cs方法。
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 綁定已被實作。 這種綁定已實作於方法 Issue 中。 其他 WS-Trust 綁定(續約、取消與驗證)在預設情況下未實作,若遇到對應這些綁定的 RST,則會回傳適當的錯誤給呼叫者。 當然,你可以覆寫適當的方法(Renew、 Cancel和 Validate),來實作這些綁定在你的 STS。
Important
實施可生產的STS需要謹慎規劃與大量資源,以降低暴露此類服務所帶來的安全風險。 大多數使用 Windows 身份基礎(WIF)的開發者,會開發將身份管理外包給 STS 的應用程式,而非自行開發 STS。 WIF 提供 Visual Studio 擴充功能——Visual Studio 2012 的身份與存取工具,協助開發者在開發環境中測試解決方案。 此工具包含一個 STS, LocalSTS你可以設定它以服務你正在開發的應用程式的特定權利要求。 欲了解更多關於身份與存取工具的資訊,請參閱 身份與存取工具 Visual Studio 2012。 在某些情況下,可能 LocalSTS 無法提供足夠功能來充分測試您的應用程式;例如,在需要開發應用程式專用的標記處理器的情境中。 在這些情況下,你可以從中 SecurityTokenService 衍生出一個或多個簡單的 STS,這些 STS 可以部署到你的開發環境中,並用來測試應用程式中的這些功能。 本節其餘部分將聚焦於該 SecurityTokenService 類別所暴露的方法,這些方法使你能實作簡單的 STS 並擴展代幣發行管線。
以下列表簡要介紹開發者在測試或開發環境中主要使用的方法。
GetScope 方法。 此方法回傳 Scope 包含 RP 資訊的物件。 此物件用於令牌發行流程的其餘部分,包含用於回應的簽署與加密憑證資訊,以及
AppliesToReplyTo(如有需要)與 位址。 你必須覆蓋這個方法。GetOutputClaimsIdentity 方法。 此方法回傳 ClaimsIdentity 一個物件,包含要返回 RP 的權利要求。 你必須覆蓋這個方法。
Issue 方法。 此方法實作了令牌請求管線,處理一個進入的安全令牌請求(RST),並回傳包含可用於與 RP 認證的令牌的回應(RSTR)。 類別中SecurityTokenService定義的許多其他方法,包括 和 GetScope 方法,都是從此方法GetOutputClaimsIdentity呼叫的。 你不必覆蓋此方法,但了解它實作的令牌請求管線可能會有幫助。
STS 是透過 SecurityTokenServiceConfiguration 類別來設定的。
給實施者的注意事項
你必須覆寫 和 GetScope(ClaimsPrincipal, RequestSecurityToken)GetOutputClaimsIdentity(ClaimsPrincipal, RequestSecurityToken, Scope) 方法。
建構函式
| 名稱 | Description |
|---|---|
| SecurityTokenService(SecurityTokenServiceConfiguration) |
從衍生類別呼叫,使用指定的設定初始化類別 SecurityTokenService 。 |
屬性
| 名稱 | Description |
|---|---|
| Principal |
取得或設定與目前實例相關的主體。 |
| Request |
接收或設定與目前實例相關的安全令牌請求(RST)。 |
| Scope |
取得或設定與目前實例相關的範圍。 |
| SecurityTokenDescriptor |
取得或設定與目前實例相關的 。SecurityTokenDescriptor |
| SecurityTokenServiceConfiguration |
會取得擁有者設定實例。 |