安全性
应用到: Service Bus for Windows Server 1.0
在 Azure 和 Windows Server 中,Service Bus 都需要访问令牌以授权对其实体的访问。由于 Microsoft 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 中的两个地方指定授权规则:
在 Service Bus for Windows Server 服务命名空间 级别,管理员指定在所有基础 Service Bus 消息传送实体(队列、主题和订阅)上拥有管理、发送和接收权限的用户列表。在 服务命名空间 的创建期间,你可向一个安全主体(一个用户或一个安全组)授予这些权限,并可在以后使用 PowerShell 命令修改它们。有关详细信息,请参阅 TechNet 上的 New-SBNamespace 和 Set-SBNamespace cmdlet。
在 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 的客户端可创建一个令牌提供商,以使用他们的 NamespaceManager 和 MessagingFactory 类。例如:
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) });
在上一示例中,用托管 Service Bus for Windows Server 的服务器名称取代 <hostname>
。用你希望访问的 服务命名空间 的名称取代 <serviceNamespace>
。
使用 MessagingFactory 的后续操作自动通过 TokenProvider 对象获得令牌,并将它包括在所有操作中。此类别也根据令牌到期时间管理令牌缓存和续订。
使用 HTTP
以下示例介绍从 SBSTS 使用 HTTP 的访问令牌获取,它驻留在 $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;
}
本例中,你可用所示格式替代 hostname
、namespace
和 username
值。
在发往 Service Bus for Windows Server 的后续消息中,客户端可将 HTTP 授权标头设置为前一示例中通过调用 GetOAuthAccessToken()
方法获得的令牌。
![]() |
---|
使用 HTTP 的客户端负责根据令牌到期时间管理令牌缓存和续订。 |