SecurityTokenService Classe
Definição
Importante
Algumas informações se referem a produtos de pré-lançamento que podem ser substancialmente modificados antes do lançamento. A Microsoft não oferece garantias, expressas ou implícitas, das informações aqui fornecidas.
A classe base abstrata que define as propriedades e métodos de um STS (serviço de token de segurança).
public ref class SecurityTokenService abstract
public abstract class SecurityTokenService
type SecurityTokenService = class
Public MustInherit Class SecurityTokenService
- Herança
-
SecurityTokenService
Exemplos
Os exemplos de código usados nos SecurityTokenService tópicos são obtidos do Custom Token
exemplo. Este exemplo fornece classes personalizadas que permitem o processamento de SWT (Tokens Web Simples) e inclui uma implementação de um STS passivo capaz de servir um token SWT. Para obter um exemplo de como implementar um STS ativo, você pode ver o Federation Metadata
exemplo. Para obter informações sobre esses exemplos e outros exemplos disponíveis para WIF e sobre onde baixá-los, consulte Índice de exemplo de código WIF. O código a seguir mostra a implementação de um STS passivo usando a SecurityTokenService classe .
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));
}
}
}
}
O código a seguir mostra como invocar um STS passivo personalizado para processar uma solicitação WS-Federation chamando o FederatedPassiveSecurityTokenServiceOperations.ProcessRequest(HttpRequest, ClaimsPrincipal, SecurityTokenService, HttpResponse) método do code-behind no default.aspx.cs
arquivo.
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 );
}
}
}
Comentários
Para criar um STS, você deve derivar da SecurityTokenService classe . Em sua classe personalizada, você deve, no mínimo, substituir os GetScope métodos e GetOutputClaimsIdentity . Com essas substituições, o STS criado usando a implementação padrão de todos os outros métodos definidos na classe é capaz de emitir tokens de segurança em resposta a RST (solicitações de token de segurança). Ou seja, a associação de problema definida na especificação WS-Trust é implementada. Essa associação é implementada no Issue método . Nenhuma das outras associações de WS-Trust (Renovar, Cancelar e Validar) são implementadas no caso padrão e uma falha apropriada é retornada ao chamador se um RST que corresponde a uma dessas associações for encontrado. É claro que você pode substituir os métodos apropriados (Renew, Cancele Validate) para implementar essas associações em seu STS.
Importante
A implementação de uma STS pronta para produção envolve um planejamento cuidadoso e recursos consideráveis para atenuar os possíveis riscos de segurança inerentes à exposição desse serviço. A maioria dos desenvolvedores que usam o WIF (Windows Identity Foundation) desenvolverá aplicativos que terceirizam o gerenciamento de identidade para um STS, em vez de desenvolver um STS em si. O WIF fornece uma extensão do Visual Studio, a Ferramenta de Identidade e Acesso para Visual Studio 2012, para ajudar os desenvolvedores a testar soluções no ambiente de desenvolvimento. Essa ferramenta inclui um STS, LocalSTS
, que você pode configurar para fornecer declarações específicas para o aplicativo que você está desenvolvendo. Para obter mais informações sobre a ferramenta Identidade e Acesso, consulte Ferramenta de Identidade e Acesso para Visual Studio 2012. Em alguns cenários, LocalSTS
pode não fornecer a funcionalidade necessária para testar adequadamente seu aplicativo; por exemplo, em um cenário que envolve o desenvolvimento de um manipulador de token personalizado para uso por um aplicativo. Nesses casos, você pode derivar de SecurityTokenService para criar um ou mais STSs simples que podem ser implantados em seu ambiente de desenvolvimento e que podem ser usados para testar esses recursos em seu aplicativo. O restante desta seção se concentra nos métodos expostos pela SecurityTokenService classe que permitem implementar um STS simples e estender o pipeline de emissão de token.
A lista a seguir fornece uma breve visão geral dos métodos de importância primária para o desenvolvedor para uso em um ambiente de teste ou desenvolvimento.
O método GetScope. Esse método retorna um Scope objeto que contém informações sobre o RP. Esse objeto é usado no restante do pipeline de emissão de token e inclui informações sobre as credenciais de assinatura e criptografia a serem usadas na resposta, bem como os
AppliesTo
endereços eReplyTo
(se necessário). Você deve substituir esse método.O método GetOutputClaimsIdentity. Esse método retorna um ClaimsIdentity objeto que contém as declarações a serem retornadas ao RP. Você deve substituir esse método.
O método Issue. Esse método implementa o pipeline de solicitação de token, que processa uma RST (solicitação de token de segurança) de entrada e retorna uma resposta (RSTR) para o chamador que contém um token que pode ser usado para autenticar com um RP. Muitos dos outros métodos definidos na SecurityTokenService classe são chamados desse método, incluindo os GetScope métodos e GetOutputClaimsIdentity . Você não precisa substituir esse método, mas uma compreensão do pipeline de solicitação de token que ele implementa pode ser útil.
Um STS é configurado por meio da SecurityTokenServiceConfiguration classe .
Notas aos Implementadores
Você deve substituir os GetScope(ClaimsPrincipal, RequestSecurityToken) métodos e GetOutputClaimsIdentity(ClaimsPrincipal, RequestSecurityToken, Scope) .
Construtores
SecurityTokenService(SecurityTokenServiceConfiguration) |
Chamado de classes derivadas para inicializar a classe SecurityTokenService usando as definições de configuração especificadas. |
Propriedades
Principal |
Obtém ou define a entidade de segurança associada à instância atual. |
Request |
Obtém ou define a solicitação (RST) de token de segurança associada à instância atual. |
Scope |
Obtém ou define o escopo associado à instância atual. |
SecurityTokenDescriptor |
Obtém ou define o SecurityTokenDescriptor associado à instância atual. |
SecurityTokenServiceConfiguration |
Obtém a instância de configuração de proprietário. |
Métodos
BeginCancel(ClaimsPrincipal, RequestSecurityToken, AsyncCallback, Object) |
Quando substituído em uma classe derivada, inicia uma solicitação Cancel do WS-Trust assíncrona. |
BeginGetOutputClaimsIdentity(ClaimsPrincipal, RequestSecurityToken, Scope, AsyncCallback, Object) |
Quando substituída em uma classe derivada, inicia uma chamada assíncrona para o método GetOutputClaimsIdentity(ClaimsPrincipal, RequestSecurityToken, Scope). |
BeginGetScope(ClaimsPrincipal, RequestSecurityToken, AsyncCallback, Object) |
Quando substituída em uma classe derivada, inicia uma chamada assíncrona para o método GetScope(ClaimsPrincipal, RequestSecurityToken). |
BeginIssue(ClaimsPrincipal, RequestSecurityToken, AsyncCallback, Object) |
Quando substituído em uma classe derivada, inicia uma solicitação Issue do WS-Trust assíncrona. |
BeginRenew(ClaimsPrincipal, RequestSecurityToken, AsyncCallback, Object) |
Quando substituído em uma classe derivada, inicia uma solicitação Renew do WS-Trust assíncrona. |
BeginValidate(ClaimsPrincipal, RequestSecurityToken, AsyncCallback, Object) |
Quando substituído em uma classe derivada, inicia uma solicitação Validate do WS-Trust assíncrona. |
Cancel(ClaimsPrincipal, RequestSecurityToken) |
Quando substituído em uma classe derivada, processa uma solicitação Cancel do WS-Trust. |
CreateSecurityTokenDescriptor(RequestSecurityToken, Scope) |
Cria uma instância de um SecurityTokenDescriptor. |
EndCancel(IAsyncResult) |
Quando substituído em uma classe derivada, conclui a solicitação Cancel do WS-Trust assíncrona. |
EndGetOutputClaimsIdentity(IAsyncResult) |
Quando substituído em uma classe derivada, conclui a chamada assíncrona para o método BeginGetOutputClaimsIdentity(ClaimsPrincipal, RequestSecurityToken, Scope, AsyncCallback, Object). |
EndGetScope(IAsyncResult) |
Quando substituído em uma classe derivada, conclui a chamada assíncrona para o método BeginGetScope(ClaimsPrincipal, RequestSecurityToken, AsyncCallback, Object). |
EndIssue(IAsyncResult) |
Quando substituído em uma classe derivada, conclui a solicitação Issue do WS-Trust assíncrona. |
EndRenew(IAsyncResult) |
Quando substituído em uma classe derivada, conclui a solicitação Renew do WS-Trust assíncrona. |
EndValidate(IAsyncResult) |
Quando substituído em uma classe derivada, conclui a solicitação Validate do WS-Trust assíncrona. |
Equals(Object) |
Determina se o objeto especificado é igual ao objeto atual. (Herdado de Object) |
GetHashCode() |
Serve como a função de hash padrão. (Herdado de Object) |
GetIssuerName() |
Obtém o nome do STS (serviço de token de segurança). |
GetOutputClaimsIdentity(ClaimsPrincipal, RequestSecurityToken, Scope) |
Quando substituído em uma classe derivada, esse método retorna uma coleção de entidades de saída a serem incluídas no token emitido. |
GetProofToken(RequestSecurityToken, Scope) |
Obtém o token de prova a ser incluído na resposta (RSTR). |
GetRequestorProofEncryptingCredentials(RequestSecurityToken) |
Obtém as credenciais de criptografia da prova do solicitante. |
GetResponse(RequestSecurityToken, SecurityTokenDescriptor) |
Cria a resposta (RSTR) que contém o token emitido usando a solicitação (RST) e o descritor de token de segurança solicitados. |
GetScope(ClaimsPrincipal, RequestSecurityToken) |
Obtém um objeto Scope que contém informações sobre a RP (terceira parte confiável) associada à solicitação (RST) especificada. Você deve substituir esse método em sua implementação da classe SecurityTokenService. |
GetSecurityTokenHandler(String) |
Obtém o manipulador de token de segurança apropriado para emitir um token de segurança do tipo especificado. |
GetTokenLifetime(Lifetime) |
Obtém o tempo de vida do token emitido. |
GetType() |
Obtém o Type da instância atual. (Herdado de Object) |
Issue(ClaimsPrincipal, RequestSecurityToken) |
Emite um token de segurança. |
MemberwiseClone() |
Cria uma cópia superficial do Object atual. (Herdado de Object) |
Renew(ClaimsPrincipal, RequestSecurityToken) |
Quando substituído em uma classe derivada, processa uma solicitação Renew do WS-Trust. |
ToString() |
Retorna uma cadeia de caracteres que representa o objeto atual. (Herdado de Object) |
Validate(ClaimsPrincipal, RequestSecurityToken) |
Quando substituído em uma classe derivada, processa uma solicitação Validate do WS-Trust. |
ValidateRequest(RequestSecurityToken) |
Valida a solicitação (RST) de token de segurança encapsulada por esta instância. |