I have an on-premise installation of Dynamics CRM 2016 which has claims-based authentication configured using an ADFS 4.0 (Server 2016) instance. Logging into CRM works fine via ADFS. I have a separate Node.js application trying to access the CRM Web API using the ADAL library provided by Microsoft to perform authentication. I have created an ADFS client using PowerShell for this Node app that has a Client ID and Secret. When the Node code executes to acquire a token from ADFS to use for calling the CRM Web API, I get the error MSIS9605: The client is not allowed to access the requested resource. Clearly the call is reaching ADFS, but I cannot seem to find a way to configure ADFS to allow the client to access the other resource protected by ADFS.

Here is the output of Get-ADFSRelyingPartyTrust:

AllowedAuthenticationClassReferences : {}
EncryptionCertificateRevocationCheck : CheckChainExcludeRoot
PublishedThroughProxy                : False
SigningCertificateRevocationCheck    : CheckChainExcludeRoot
WSFedEndpoint                        : https://crm.mysite.com/
AdditionalWSFedEndpoint              : {}
ClaimsProviderName                   : {}
ClaimsAccepted                       : {, , }
EncryptClaims                        : True
Enabled                              : True
EncryptionCertificate                : [Subject]
                                         CN=*.mysite.com, OU=Domain Control Validated

                                         CN=Go Daddy Secure Certificate Authority - G2, 
                                       OU=http://certs.godaddy.com/repository/, O="GoDaddy.com, Inc.", L=Scottsdale, 
                                       S=Arizona, C=US

                                       [Serial Number]

                                       [Not Before]
                                         11/23/2016 9:41:00 PM

                                       [Not After]
                                         1/19/2018 3:51:41 PM


Identifier                           : {https://demo.mysite.com/, https://crm.mysite.com/}
NotBeforeSkew                        : 0
EnableJWT                            : True
AlwaysRequireAuthentication          : False
Notes                                : 
OrganizationInfo                     : 
ObjectIdentifier                     : 8e869c1e-..........8b5a
ProxyEndpointMappings                : {}
ProxyTrustedEndpoints                : {}
ProtocolProfile                      : WsFed-SAML
RequestSigningCertificate            : {}
EncryptedNameIdRequired              : False
SignedSamlRequestsRequired           : False
SamlEndpoints                        : {}
SamlResponseSignature                : AssertionOnly
SignatureAlgorithm                   : http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
TokenLifetime                        : 0
AllowedClientTypes                   : Public, Confidential
IssueOAuthRefreshTokensTo            : AllDevices
RefreshTokenProtectionEnabled        : True
RequestMFAFromClaimsProviders        : False
ScopeGroupId                         : 
Name                                 : crm.mysite.com
AutoUpdateEnabled                    : True
MonitoringEnabled                    : True
MetadataUrl                          : https://crm.mysite.com/federationmetadata/2007-06/federationmetadata.xml
ConflictWithPublishedPolicy          : False
IssuanceAuthorizationRules           : 
IssuanceTransformRules               : @RuleTemplate = "PassThroughClaims"
                                       @RuleName = "Pass Through UPN"
                                       c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"]
                                        => issue(claim = c);

                                       @RuleTemplate = "PassThroughClaims"
                                       @RuleName = "Pass Through Primary SID"
                                       c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid"]
                                        => issue(claim = c);

                                       @RuleTemplate = "MapClaims"
                                       @RuleName = "Transform Windows Account Name to Name"
                                       c:[Type == 
                                        => issue(Type = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", 
                                       Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, Value = c.Value, 
                                       ValueType = c.ValueType);

                                       @RuleTemplate = "PassThroughClaims"
                                       @RuleName = "App Claim"
                                       c:[Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-clie
                                        => issue(claim = c);

DelegationAuthorizationRules         : 
LastPublishedPolicyCheckSuccessful   : True
LastUpdateTime                       : 1/4/2017 8:24:16 PM
LastMonitoredTime                    : 1/5/2017 8:02:07 PM
ImpersonationAuthorizationRules      : 
AdditionalAuthenticationRules        : 
AccessControlPolicyName              : Permit everyone
AccessControlPolicyParameters        : 
ResultantPolicy                      : RequireFreshAuthentication:False
                                         Permit everyone

Here is the Node.js function using ADAL (https://github.com/AzureAD/azure-activedirectory-library-for-nodejs). I realize it has Azure in the title but it is successfully communicating with ADFS and there are comments in the issues log stating that what I am doing is possible.

let ADAuthenticationContext = require('adal-node').AuthenticationContext;

const authorityHostUrl = 'https://sso.mysite.com';
const tenant = 'adfs';
let authorityUrl = authorityHostUrl + '/' + tenant;
const clientId = 'c43002e2-............67c';
const clientSecret = 'lT..................jjh';

const resource = 'https://crm.mysite.com/';

let crm = module.exports = {};

let context = new ADAuthenticationContext(authorityUrl, false);

crm.test = function() {
    context.acquireTokenWithClientCredentials(resource, clientId, clientSecret, function(err, tokenResponse) {
        if (err) {
            console.log('well that didn\'t work: ' + err.stack);
        } else {

Also, from the ADFS Event Log:

Encountered error during OAuth token request. 

Additional Data 

Exception details: 
Microsoft.IdentityServer.Web.Protocols.OAuth.Exceptions.OAuthUnauthorizedClientException: MSIS9321: Received invalid OAuth request. The client 'c43002e2-f1a6-4786-9234-f71e971c167c' is forbidden to access the resource 'https://demo.mysite.com/'.
   at Microsoft.IdentityServer.Web.Protocols.OAuth.OAuthProtocolContext.ValidateScopes(String scopeParameter, String clientId, String relyingPartyId)
   at Microsoft.IdentityServer.Web.Protocols.OAuth.OAuthToken.OAuthClientCredentialsContext.ValidateCore()

Any insight would be great as I am pretty new to ADFS and the message seems to indicate something in ADFS is not correct.


On Windows Server 2016 you need to explicitly grant clients permission to a resource, even when the access policy is set to "Permit everyone".

Try this command:

Grant-AdfsApplicationPermission -ClientRoleIdentifier "clientName" -ServerRoleIdentifier "https://service.url"
  • Thanks a lot! That works for me. Dec 2 '20 at 15:32

You need to create a rule to permit or deny users based on an incoming claim.

In Windows Server 2016, you can use an Access Control Policy to create a rule that will permit or deny users based on an incoming claim. Also, you can permit all users to access the relying party, use the Permit Everyone Access Control Policy or the Permit All Users rule template

You can refer to the article below for creating the rule by using the AD FS Management.


Or you also can use the following command with related parameters running in PowerShell.

Add-ADFSRelyingPartyTrust -Name "Fabrikam" -MetadataURL "https://fabrikam.com/federationmetadata/2007-06/federationmetadata.xml" -IssuanceAuthorizationRules '=> issue(Type ="http://schemas.microsoft.com/authorization/claims/permit", value="true");'
  • The existing relying party trust already was already using the Permit Everyone rule template. Do I need to create another relying party trust for the Node app?
    – DaveTrux
    Jan 6 '17 at 15:56
  • I recommend to create relying party trust by using command in PowerShell, and please make sure add the following in the command. -IssuanceAuthorizationRules '=> issue(Type ="schemas.microsoft.com/authorization/claims/permit", value="true");' Jan 9 '17 at 1:58
  • I deleted the relying party trust and recreated it using PowerShell following your template. No change, error still persists.
    – DaveTrux
    Jan 9 '17 at 14:54
  • How did you register the Node App with ADFS by using PowerShell? Did you set the client type as Public or Confidential? You may refer to the article AD FS Scenarios for Developers for the scenarios in Windows Server 2016. Jan 11 '17 at 5:22
  • 1
    BTW, in answer to Andy's question it was set to public. Via a support call with Microsoft they told me CRM with ADFS 4.0 is unsupported as of this date.
    – DaveTrux
    Jan 24 '17 at 18:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.