ADFS 错误 - MSIS9605:不允许客户端访问请求的资源

ADFS 错误 - MSIS9605:不允许客户端访问请求的资源

我有一个 Dynamics CRM 2016 的本地安装,它使用 ADFS 4.0(Server 2016)实例配置了基于声明的身份验证。通过 ADFS 登录 CRM 工作正常。我有一个单独的 Node.js 应用程序,尝试使用 Microsoft 提供的 ADAL 库访问 CRM Web API 以执行身份验证。我已使用 PowerShell 为此 Node 应用程序创建了一个 ADFS 客户端,该客户端具有客户端 ID 和密钥。当执行 Node 代码以从 ADFS 获取令牌以用于调用 CRM Web API 时,我收到错误MSIS9605:不允许客户端访问请求的资源。显然,调用已到达 ADFS,但我似乎找不到配置 ADFS 以允许客户端访问受 ADFS 保护的其他资源的方法。

以下是输出获取 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

                                       [Issuer]
                                         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]
                                         2DC..............91

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

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

                                       [Thumbprint]
                                         2FC..................AADD

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 == 
                                       "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"]
                                        => 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
                                       nt-application"]
                                        => 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
                                       IssuanceAuthorizationRules:
                                       {
                                         Permit everyone
                                       }

以下是使用 ADAL 的 Node.js 函数 (https://github.com/AzureAD/azure-activedirectory-library-for-nodejs)。我意识到标题中有 Azure,但它成功地与 ADFS 通信,并且问题日志中有注释表明我所做的事情是可能的。

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 {
            console.log(tokenResponse);
        }
    });
};

此外,从 ADFS 事件日志中可以看到:

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()

任何见解都很有帮助,因为我对 ADFS 还很陌生,而且该消息似乎表明 ADFS 中的某些内容不正确。

答案1

在 Windows Server 2016 上,您需要明确授予客户端对资源的权限,即使访问策略设置为“允许所有人”。

尝试这个命令:

Grant-AdfsApplicationPermission -ClientRoleIdentifier "clientName" -ServerRoleIdentifier "https://service.url"

答案2

您需要创建一条规则,根据传入的声明来允许或拒绝用户。

在 Windows Server 2016 中,您可以使用访问控制策略创建规则,该规则将根据传入声明允许或拒绝用户。此外,您可以允许所有用户访问信赖方,使用允许所有人访问控制策略或允许所有用户规则模板

您可以参考以下文章使用 AD FS 管理创建规则。

https://technet.microsoft.com/en-us/windows-server-docs/identity/ad-fs/operations/create-a-rule-to-permit-or-deny-users-based-on-an-incoming-claim?f=255&MSPPError=-2147217396

或者您也可以使用以下命令并结合相关参数在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");'

相关内容