Using IdentityServer to issue tokens for Windows Server ServiceBus

Windows Server ServiceBus supports SWT tokens to authorize actions on a SB namespace or entity (e.g. listen, send or manage).

In the Azure version of ServiceBus you would use the Azure Access Control Service to issue such tokens. In the on-premise version of ServiceBus you could do the same, but often you want to use an on-premise token issuer here as well.

This is where IdentityServer can help out! In this post, I mentioned, that I added Simple Web Token (SWT) support back to IdentityModel – which means that IdentityServer can issue SWT tokens as well.

Clemens and I exchanged some code snippets and ideas to bring the moving parts together – and the following is a walkthrough of how you could use IdentityServer to issue tokens for Windows Server ServiceBus to authorize access.

Step 0 – Enable SWT support and the SimpleHttp endpoint
Both SWT support and the SimpleHttp token endpoint are not enabled by default.

Use the admin area to enable the protocol:

image

…and uncomment the SWT handler in WebSite\Configuration\identity.config:

<!-- SWT -->
<add type="Thinktecture.IdentityModel.Tokens.SimpleWebTokenHandler, … " />

 

Step 1 – Create a relying party in IdentityServer
Start with creating a relying party that represents the SB namespace:

image

Possible realm names for SB are (check the docs for more info):

  • http://{server-host-name} /{namespace}/ – complete namespace
  • http://{server-host-name}/{namespace} /myqueue – for a specific queue
  • http://{server-host-name}/{namespace} /mytopic – for a specific topic
  • http://{server-host-name} /{namespace} /mytopic/subscriptions/mysub – for a specific subscription

The namespace would be swttest in our case. Also generate a symmetric signing key.

Step 2 – Configure ServiceBus
You use the SB Powershell cmdlets to configure the SB namespace. For that you need the symmetric signing key you just created and the issuer Issuer URI (that’s the Site ID on IdSrv’s general config page).

set-sbnamespace -IssuerUri http://idsrvsiteid -IssuerName http://idsrvsiteid -PrimarySymmetricKey fWUU…N4 -Name swttest

See the docs for more information.

Step 3 – Provide SB specific claims
To provide the SB specific claims (send, listen and manage) you need to provide a claims repository. I wrote about the general process of customizing IdentityServer here. You basically need to implement IClaimsRepository (or derive from the existing standard one) to get involved in providing the claims for the outgoing token.

The following sample repository illustrates the idea:

public class MyClaimsRepository : ProviderClaimsRepository
{
    string sbClaimType = "net.windows.servicebus.action";
 
    public override IEnumerable<Claim> GetClaims(
ClaimsPrincipal principal, RequestDetails
requestDetails)
    {
        if (requestDetails.Realm.Uri.AbsoluteUri == "http://sbserver/swttest/")
        {
            if (principal.Identity.Name == "bob")
            {
                return new List<Claim>
                {
                    new Claim(sbClaimType, "Listen"),
                    new Claim(sbClaimType, "Manage"),
                };
            }
            else
            {
                return new List<Claim>
                {
                    new Claim(sbClaimType, "Send"),
                };
            }
        }
 
        return base.GetClaims(principal, requestDetails);
    }
}

 

Step 7 – Request the token
To request a token you can use the SimpleHttp endpoint. This endpoint uses a simple GET request with two querystring parameters for realm and token type. The user needs to authenticate via Basic Authentication. In return you get a token response that contains the token and lifetime information.

var client = new HttpClient {

    BaseAddress = new Uri(Constants.IdSrv.SimpleHttpEndpoint)

};

 

client.SetBasicAuthentication(“bob”, “abc!123”);

 

var response = client.GetAsync(
 
“?realm=http://sbserver/swttest/&tokentype=swt”
).Result;

response.EnsureSuccessStatusCode();

 

var tokenResponse = response.Content.ReadAsStringAsync().Result;

var token = JObject.Parse(tokenResponse)[“access_token”].ToString();

 

(I am using Json.Net to parse the token response)

Step 8 – Use the token
OK – the last step is to use the token with ServiceBus – that is as simple as:

StaticSimpleWebTokenProvider tp = new StaticSimpleWebTokenProvider(token);
            
MessagingFactory factory =
    MessagingFactory.Create("sb://sbserver/swttest/", tp);
            
var qc = factory.CreateQueueClient("swttest");
qc.Send(new BrokeredMessage());

 

(The full source code can be found here.)

HTH

This entry was posted in Azure, IdentityModel, IdentityServer. Bookmark the permalink.

8 Responses to Using IdentityServer to issue tokens for Windows Server ServiceBus

  1. Adam says:

    Hi Dominick. Thanks for documenting a great story. I notice that the project references Azure Service Bus 2.1 rather than Windows Service Bus 1.0. Was this intentional? I didn’t think those versions had feature parity?!

    Do you have a sample or any guidance that demonstrates a REST service (Web API) behind Windows Service Bus 1.0 that is authenticated using tokens issued by IdentityServer?

    • Clemens provided the sample – feel free to ping him @clemensv

      • Adam says:

        Thanks Dominick. I dropped him a message via the “Contact the Author” form he has on his site the day after you’ve replied but yet to receive a reply so I guess he’s been busy.

  2. Brian says:

    I downloaded the latests Identity Server release and did not see the SWT section in identity.config. Is that change required?

  3. Brian says:

    I was using the 2.2.0 build, the 2.2.1 source has it. Thanks!

  4. Brian says:

    I’ve tried this above sample code and keep getting a 401 response upon requesting the token. I have basic authenication enabled in IIS and my user I’m loggin in with has read permissions to the site’s local folder. Any ideas?

  5. You don’t need basic auth enabled in IIS. It is all handled by IdSrv. Check the wiki for more info on setup.

Leave a reply to Brian Cancel reply