Segurança

Tanto no Windows Azure quanto no Windows Server, o Service Bus requer tokens de acesso para autorizar o acesso às suas entidades. Uma vez que o Acess Control do Active Directory do Windows Azure (também conhecido como Access Control Service ou ACS) não está disponível no Windows Server, o Service Bus for Windows Server inclui um Serviço de Token de Segurança do Service Bus (SBSTS) simples. O SBSTS é integrado com o modelo de segurança do Windows e pode emitir Simple Web Tokens (SWTs) baseados em identidades do Windows (armazenadas no repositório de identidades local do Windows ou no Active Directory).

Configuração do Service Bus for Windows Server

O SBSTS é parte do gateway Service Bus for Windows Server e funciona em cada um dos hosts de farm Service Bus for Windows Server. As configurações do SBSTS são inicializadas quando o namespace de serviço é criado.

Há dois locais no Service Bus for Windows Server em que você pode especificar regras de autorização:

  1. No nível Service Bus for Windows Server namespace de serviço, um administrador especifica uma lista de usuários que tenham permissões para gerenciar, enviar e receber em todas as entidades de troca de mensagem subjacentes do Service Bus (filas, tópicos e assinaturas). Você pode conceder essas permissões a um elemento de segurança (um usuário ou um grupo de segurança) durante a criação do namespace de serviço, e pode modificá-los posteriormente utilizando um comando do PowerShell. Para obter mais informações, consulte os cmdlets New-SBNamespace e Set-SBNamespace.

  2. No nível de entidade de troca de mensagens do Service Bus for Windows Server (fila ou tópico), você pode especificar regras de autorização para essa entidade. A regra Manage controla se o usuário pode gerenciar permissões, bem como criar, alterar ou excluir entidades. A regra Send controla se o usuário pode enviar mensagens para uma entidade do Service Bus for Windows Server e Receive controla se o usuário pode receber mensagens da entidade do Service Bus for Windows Server. Para configurar os direitos de acesso de uma entidade, o administrador deve configurar as regras de autorização. Essa ação requer a permissão Manage no namespace de serviço.

Um usuário com a permissão Manage no namespace de serviço pode adicionar regras de autorização às entidades no namespace de serviço. Por exemplo, uma vez que criou uma instância NamespaceManager, poderá adicionar as regras de autorização quando uma entidade for criada, ou poderá modificá-las em uma entidade existente. O seguinte exemplo, adiciona as regras de autorização ao criar uma fila:

// Example of allowing a domain group manage and send permissions to a queue
QueueDescription sourceQ = new QueueDescription(sourceQName);
string domainGroup = “MyGroup@" + Environment.GetEnvironmentVariable("USERDNSDOMAIN"); 
AuthorizationRule sourceQRule = new AllowRule("owner", RoleClaimType, domainGroup, new List<string>() {"Manage", "Send" });
sourceQ.Authorization.Add(sourceQRule );

// Example of granting a domain user listen permissions to a queue
string domainUser = “MyUserName@" + Environment.GetEnvironmentVariable("USERDNSDOMAIN");
AuthorizationRule ListenRule = new AllowRule("owner", IdentityClaimType, domainUser, new List<string>() { "Listen" });
sourceQ.Authorization.Add(ListenRule);
namespaceManager.CreateQueue(sourceQ);

O exemplo anterior criou uma fila (sourceQ) com duas regras de autorização: concedendo ao grupo (MYGroup) permissões para gerenciar e enviar, e concedendo ao usuário (MyUserName) a permissão de ouvir.

Acessando o Service Bus for Windows Server

Clientes que acessam um namespace de serviço ou uma entidade no Service Bus for Windows Server devem adquirir um token do SBSTS para qualquer operação.

Observação

A vida útil padrão dos tokens emitidos pelo SBSTS é de 20 minutos.

Usando o Service Bus for Windows Server SDK

É possível obter acesso a uma entidade do Service Bus obtendo um token do STS. Por padrão, um $STS usado no Service Bus for Windows Server escuta na porta 9355.

Clientes que usam o Service Bus for Windows Server podem criar um provedor de token para usar com as suas classes NamespaceManager e MessagingFactory. Por exemplo:

stsUris= new List<Uri>() { new Uri(string.Format(CultureInfo.InvariantCulture, 
    "sb://{0}:9355/", <hostname>)) };
TokenProvider tokenProvider = TokenProvider.CreateWindowsTokenProvider(stsUris);

string runtimeAddress = string.Format("sb://{0}:9354/{1}/", <hostname>,  
    <serviceNamespace>);
MessagingFactory messagingFactory = MessagingFactory.Create(runtimeAddress, 
    new MessagingFactorySettings() { TokenProvider = this.tokenProvider, 
    OperationTimeout = TimeSpan.FromMinutes(30) });

No exemplo anterior, substitua <hostname> pelo nome do servidor que hospeda o Service Bus for Windows Server. Substitua <serviceNamespace> pelo nome do namespace de serviço que você deseja acessar.

As operações subsequentes que usam MessagingFactory irão adquirir automaticamente o token por meio do objeto TokenProvider e incluí-lo em todas as operações. Essa classe também gerencia o cache de token e a renovação com base no tempo de expiração do token.

Usando HTTP

O exemplo a seguir ilustra a aquisição de token de acesso usando HTTP do SBSTS, que reside no endereço $STS.

public static void Usage()
{
    string token = GetOAuthAccessToken(new 
        Uri("https://<hostname.domain.com>:9355/<namespace> /"), 
        "user@corp.domain. com", "<password>", TimeSpan.FromMinutes(10)); 
}

public static string GetOAuthAccessToken(Uri namespaceBaseAddress, string userName, string userPassword, TimeSpan timeout)
{
    const int ServicePointMaxIdleTimeMilliSeconds = 50000;
    const string OAuthTokenServicePath = "$STS/OAuth/";
    const string ClientPasswordFormat = 
        "grant_type=authorization_code&client_id={0}&client_secret={1}&scope={2}";

    Uri requestUri = new Uri(namespaceBaseAddress, OAuthTokenServicePath);
    string requestContent = string.Format(CultureInfo.InvariantCulture, 
        ClientPasswordFormat, HttpUtility.UrlEncode(userName), 
        HttpUtility.UrlEncode(userPassword), 
        HttpUtility.UrlEncode(namespaceBaseAddress.AbsoluteUri));
    byte[] body = Encoding.UTF8.GetBytes(requestContent);

    HttpWebRequest request = WebRequest.Create(requestUri) as HttpWebRequest;
    request.ServicePoint.MaxIdleTime = ServicePointMaxIdleTimeMilliSeconds;
    request.AllowAutoRedirect = true;
    request.MaximumAutomaticRedirections = 1;
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = body.Length;
    request.Timeout = Convert.ToInt32(timeout.TotalMilliseconds, 
        CultureInfo.InvariantCulture);

    using (Stream requestStream = request.GetRequestStream())
    {
        requestStream.Write(body, 0, body.Length);
    }

    string rawAccessToken = null;
    using (var response = request.GetResponse() as HttpWebResponse)
    {
        using (Stream stream = response.GetResponseStream())
        {
            using (var reader = new StreamReader(stream, Encoding.UTF8))
            {
                rawAccessToken = reader.ReadToEnd();
            }
        }
    }

    string simpleWebToken = string.Format(CultureInfo.InvariantCulture, 
        "WRAP access_token=\"{0}\"", rawAccessToken);
    return simpleWebToken;
}

No exemplo, você pode substituir os valores hostname, namespace e username no formato exibido.

Nas mensagens subsequentes para o Service Bus for Windows Server, o cliente pode obter o cabeçalho de Autorização HTTP no token obtido a partir da chamada ao método GetOAuthAccessToken() do exemplo anterior.

Observação

Os clientes usando HTTP são responsáveis por gerenciar o cache de token e a renovação com base no tempo de expiração do token.

Data da compilação:

2013-07-25