安全性

注:本页面内容可能不完全适用中国大陆地区运营的 Windows Azure服务。如要了解不同地区 Windows Azure 服务的差异, 请参考本网站.

在 Windows Azure 和 Windows Server 中,Service Bus 需要访问令牌才能授予对其实体的访问权限。由于 Windows Azure Active Directory 访问控制(也称为访问控制服务或 ACS) 在 Windows Server 上不可用,因此 Service Bus for Windows Server 包含简单的 Service Bus 安全令牌服务 (SBSTS)。SBSTS 与 Windows 安全模型集成,并可基于 Windows 标识(存储在本地 Windows 标识存储区或 Active Directory 中)颁发简单 Web 令牌 (SWT)。

Service Bus for Windows Server 配置

SBSTS 是 Service Bus for Windows Server 网关的一部分,并在每个 Service Bus for Windows Server 场主机上运行。创建服务命名空间时,将初始化 SBSTS 设置。

Service Bus for Windows Server 中有两个可以指定授权规则的位置:

  1. 在 Service Bus for Windows Server 服务命名空间级别,管理员指定对所有基础 Service Bus 消息实体(队列、主题和订阅)具有管理发送接收权限的一组用户。在创建服务命名空间期间,可以将这些权限授予安全主体(用户或安全组),以后可以使用 PowerShell 命令修改这些权限。有关更多信息,请参见 New-SBNamespaceSet-SBNamespace cmdlet。

  2. 在 Service Bus for Windows Server 消息实体级别(队列或主题),你可以为该实体指定授权规则。管理规则控制用户是否可以管理权限以及创建、更改或删除实体。发送规则控制用户是否可以向 Service Bus for Windows Server 实体发送消息,而接收控制用户是否可以从 Service Bus for Windows Server 实体接收消息。若要配置实体的访问权限,管理员必须配置授权规则。此操作要求对服务命名空间具有管理权限。

然后,对服务命名空间具有管理权限的用户可以向服务命名空间中的实体添加授权规则。例如,创建了 NamespaceManager 实例后,便可以在创建实体时添加授权规则,也可以对现有实体修改授权规则。以下示例在创建队列时添加授权规则:

// 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);

前面的示例创建了一个具有两个授权规则的队列 (sourceQ):授予组 (MYGroup)“管理”和“发送”权限,并授予用户 (MyUserName)“侦听”权限。

访问 Service Bus for Windows Server

访问 Service Bus for Windows Server 上的服务命名空间或实体的客户端必须从 SBSTS 获取任何操作的令牌。

备注

SBSTS 颁发的令牌的默认生存期为 20 分钟。

使用 Service Bus for Windows Server SDK

可以通过从 STS 获取令牌来获得对 Service Bus 实体的访问权限。默认情况下,Service Bus for Windows Server 中使用的 $STS 侦听端口 9355。

使用 Service Bus for Windows Server 的客户端可以创建令牌提供程序以用于其 NamespaceManagerMessagingFactory 类。例如:

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) });

在前面的示例中,将 <hostname> 替换为托管 Service Bus for Windows Server 的服务器的名称。将 <serviceNamespace> 替换为你要访问的服务命名空间的名称。

使用 MessagingFactory 的后续操作将通过 TokenProvider 对象自动获取令牌,并将其包含在所有操作中。此类还基于令牌到期时间管理令牌缓存和续订。

使用 HTTP

以下示例说明了使用 HTTP 从 SBSTS(驻留在 $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;
}

在此示例中,你可以使用所示格式替换 hostnamenamespaceusername 值。

在发往 Service Bus for Windows Server 的后续消息中,客户端可以将 HTTP 授权标头设置为通过调用前面示例中的 GetOAuthAccessToken() 方法获取的令牌。

备注

使用 HTTP 的客户端负责基于令牌到期时间管理令牌缓存和续订。

生成日期:

2013-09-12