1

My goal is to use the Microsoft Rights Management SDK 4.2 on a Linux system to access and manage protected documents.

I am unable to authenticate to the RMS server via a Federation Server (this is the setup that the SDK requires).

I have the following setup:

  • A domain controller, dc1.mydomain
  • A rights management server, rms1.mydomain, with Active Directory Rights Management Services, SQL Server, and the Mobile Device Extension for AD RMS
  • An authentication server, fs1.mydomain, running Federation Services

All hosts in the cluster run Windows Server 2016 and have certificates signed by a Registration Authority. The root CA and intermediate RA certificates are installed on the hosts. The token signing certificate and token decrypting certificates for the Federation Service are also signed by the RA.

Microsoft Office applications (which use an earlier SOAP protocol) are able to talk to the RMS service. The RIghts Management SDK library uses a more lightweight JSON protocol provided by the Mobile Device Extension.

I have configured an SRV DNS record for _rmsdisco._http._tcp.mydomain.

The Mobile Device Extension has been configured to use https://fs1.mydomain for authentication.

On fs1.mydomain, I have configured a "Server application accessing a web API". The server application has client ID <ID> and client secret <SECRET>. The web API has the relying party identifier api.rms.rest.com.

I am unable to get the RMS SDK client to authenticate to the RMS server with the client application credentials. This is the failing oauth2 exchange:

  1. Attempt to fetch https://rms1.mydomain:443/my/v2/servicediscovery?email=user1@mydomain
  2. This returns a 401 response with the expected WWW-Authenticate header:
    WWW-Authenticate: Bearer realm="api.rms.rest.com", authorization="https://fs1.mydomain/adfs/oauth2/authorize"
  3. POST the following body to https://fs1.mydomain/adfs/oauth2/token:
    grant_type=client_credentials&client_id=<ID>&client_secret=<SECRET>&resource=api.rms.rest.com
  4. Obtain a signed authentication token with a decoded body looking something like this:
    {"aud":"microsoft:identityserver:api.rms.rest.com","iss":"http://fs1.mydomain/adfs/services/trust","iat":1553792250,"exp":1553795850,"apptype":"Confidential","appid":"<ID>","authmethod":"http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/password","auth_time":"2019-03-28T16:57:30.037Z","ver":"1.0"}
  5. Attempt to fetch the service discovery URI again, this time adding the following header:
    Authorization: Bearer <TOKEN>
  6. Server returns a 401 response instead of 200.

I'm assuming that there is an error in the server configuration but don't know what. I'm not seeing anything logged in the RMS server but I'd guess that it's failing to verify the oauth token. The token signing certificate is present in the FederationData.xml supplied by the Federation Server. I have also installed it on the RMS server under "Certificates" (the certificate authority certificates are also present).

At this point, I'm stuck, hence reaching out for help.

  • I have the exact same issue you described but my bearer token does have the email, how did you end up fixing this? – Jan Martin Jun 22 '21 at 07:20

1 Answers1

0

Apologies for answering my own question. The problem with the bearer token appears not to be failure to verify the signature but a missing claim (email at a guess) in the payload.

Install and configure the AD RMS Mobile Device Extension as documented here.

There is something else you need to do that isn't documented (and which I'd guess is new for Windows Server 2016). After you add an ADFS client in Powershell, for example, the MAC OS X RMS Sharing App:

Add-AdfsClient -Name "RMS Sharing App for macOS" -ClientId "96731E97-2204-4D74-BEA5-75DCA53566C3" -RedirectUri @("com.microsoft.rms-sharing-for-osx://authorize")

You then need to grant the client ID permission to access the protected resource (even if you configured "Permit Access to All Users"):

Grant-AdfsApplicationPermission -ClientRoleIdentifier "96731E97-2204-4D74-BEA5-75DCA53566C3" -ServerRoleIdentifier "api.rms.rest.com"

Now you can authenticate using the client ID and valid credentials for a domain user. The authentication request body becomes:
grant_type=password&client_id=96731e97-2204-4d74-bea5-75dca53566c3&username=user1@mydomain&password=mypassword&resource=api.rms.rest.com

The returned token has a payload something like this:
{"aud":"microsoft:identityserver:api.rms.rest.com","iss":"http://fs1.mydomain/adfs/services/trust","iat":1553874942,"exp":1553878542,"email":"user1@mydomain","upn":"user1@mydomain","apptype":"Public","appid":"96731E97-2204-4D74-BEA5-75DCA53566C3","authmethod":"urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport","auth_time":"2019-03-29T15:55:42.124Z","ver":"1.0"}

This token is accepted by the RMS server.

One small detail: the service discovery URL is not quite correct. Even with a working bearer token, attempting to access https://rms1.mydomain:443/my/v2/servicediscovery?email=user1@mydomain will result in a 404 response. Replace "v2" with "v1" and the response is 200. My confusion was due to the SDK effectively hardcoding "/my/v2".

A couple more questions remain:

  1. Is it possible to get the RMS Mobile Device Extension to accept a token that doesn't contain an email claim? This is required for client ID / client secret authentication to work.
  2. What is the difference between "/my/v1" and "/my/v2" and how does one know which one to use?