I have a Spring Boot application that gets access token from the Azure authentication endpoint successfully. But when I try to use the same token to access Dynamics CRM Online REST API, I am getting - 401 Unauthorized: [no body]
This is how I get my access token
@Bean(name = "oAuth2RestTemplate")
public OAuth2RestTemplate oAuth2RestTemplate() {
String tokenUri = "https://login.windows.net/<tenant id>/oauth2/token";
ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails();
resourceDetails.setId("1");
resourceDetails.setAccessTokenUri(tokenUri);
resourceDetails.setClientId(clientid);
resourceDetails.setClientSecret(clientsecret);
resourceDetails.setGrantType("client_credentials");
resourceDetails.setScope(Arrays.asList("read", "write"));
AccessTokenRequest atr = new DefaultAccessTokenRequest();
atr.add("resource", "https://my.api.crm9.dynamics.com");
OAuth2ClientContext clientContext = new DefaultOAuth2ClientContext(atr);
OAuth2RestTemplate oauth2RestTemplate = new OAuth2RestTemplate(resourceDetails, clientContext);
return oauth2RestTemplate;
}
This is what I get as my accesstoken using this OAuth2RestTemplate -
{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCIsImtpZCI6ImtnMkxZczJUMENUaklmajRydDZKSXluZW4zOCJ9.eyJhdWQiOiIwMDAwMDAwMi0wMDAwLTAwMDAtYzAwMC0wMDAwMDAwMDAwMDAiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC82MDQwOTE1Yi05ZGZmLTRkNDctYmIzNS04YWM5YzlhNWRjMTgvIiwiaWF0IjoxNjAyNjcxNzYyLCJuYmYiOjE2MDI2NzE3NjIsImV4cCI6MTYwMjY3NTY2MiwiYWlvIjoiRTJSZ1lQRGlWbHRZZlYxNHc5TTMxMmFmQ3BUWEFnQT0iLCJhcHBpZCI6IjM2NDlmNTUxLTRlMjEtNDY3OS04YThjLTA4ZDhmNmIwOTA3MSIsImFwcGlkYWNyIjoiMSIsImlkcCI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzYwNDA5MTViLTlkZmYtNGQ0Ny1iYjM1LThhYzljOWE1ZGMxOC8iLCJvaWQiOiJiM2FmOTcxYi1lMDQ5LTQ1ZDktOTViNy1hMTg3ZjQ4MWQzNWYiLCJyaCI6IjAuQVMwQVc1RkFZUC1kUjAyN05Zckp5YVhjR0ZIMVNUWWhUbmxHaW93STJQYXdrSEV0QUFBLiIsInN1YiI6ImIzYWY5NzFiLWUwNDktNDVkOS05NWI3LWExODdmNDgxZDM1ZiIsInRlbmFudF9yZWdpb25fc2NvcGUiOiJOQSIsInRpZCI6IjYwNDA5MTViLTlkZmYtNGQ0Ny1","token_type":"Bearer","expires_in":3528,"ext_expires_in":"3599","expires_on":"1602675662","not_before":"1602671762","resource":"**00000002-0000-0000-c000-000000000000**"}
As you can see, the resource in the access token is different than my desired resource endpoint - https://my.api.crm9.dynamics.com
I am trying to access my rest service this way -
public List<Contact> findContacts() throws MalformedURLException, IOException {
System.out.println("getting access token");
final UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(
"https://my.api.crm9.dynamics.com").path("/api/data/v9.1/contacts?$select=_accountid,address_stateorprovince," +
"contactid,emailaddress,fullname&$filter=startswith(emailaddress,'something')");
final String url = uriComponentsBuilder.build().toUriString();
System.out.println("url is :: "+url);
try {
ResponseEntity<List<Contact>> response = oAuth2RestTemplate.exchange(url, HttpMethod.GET, createRequestEntity(),
new ParameterizedTypeReference<List<Contact>>() {});
List<Contact> contacts = null;
if (null != response) {
contacts = response.getBody();
}
return contacts;
} catch (final Exception e) {
log.error(e.getMessage());
log.error("<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
log.error("Failed to retrieve contacts from Dynamics CRM.", e);
return new ArrayList<>();
}
I have looked at OAuth2.0 authentication of Dynamics CRM WebAPIs from a background Java (Spring) application Resource(the web api base url) is being set in the DefaultAccessTokenRequest but that does not seem to have any impact in my case.
My theory is the resource in the access token being different is causing a 401 while trying to access the rest endpoint. But I cannot seem to be able to set the resource explicitly. My questions -
- Any other theories for my 401?
- How can I explicitly set my resource in my access token? I have tried doing it in my DefaultAccessTokenRequest while creating my OAuth2RestTemplate