我正在尝试使用第三方身份提供商PingFed连接到Dynamics 365在线实例。我不负责此身份提供者的配置,也无权访问其任何设置。
使用下面的代码,我能够识别身份验证提供者并成功进行身份验证,但是,一旦我们重定向到Microsoft登录服务,就会引发错误,这是我通过Fiddler捕获的。查看SAML断言时,它是SAML 1.1。
我们收到的错误是:
The request is not a valid SAML 2.0 protocol message
如果我使用交互式提示进行身份验证,则能够成功登录。这不能满足我们的需求,因为我们需要具有一个服务帐户来对CRM进行身份验证。
为什么当我们以交互方式登录时却能正常工作,而在尝试通过代码登录时却无法正常工作?
负责管理身份验证的团队无法提供帮助,所以我希望有人可以对发生的事情有所了解?
public static void OverrideExample(bool usePrompt = false)
{
try
{
// Define organization Url
Uri orgUrl = new Uri("https://myorg.crm6.dynamics.com");
bool usePrompt = false;
// Call your existing authentication implementation
AuthenticationResult accessToken = MichelOverrideExampleHookImplementation.GetAccessTokenFromAzureAD(orgUrl, usePrompt);
// Create instance of your hook
var hook = new MichelOverrideExampleHookImplementation();
// Add token to your hook
hook.AddAccessToken(orgUrl, accessToken);
// Register the hook with the CrmServiceClient
CrmServiceClient.AuthOverrideHook = hook;
// Create a new instance of CrmServiceClient, pass your organization url and make sure useUniqueInstance = true!
var client = new CrmServiceClient(orgUrl, useUniqueInstance: true);
if (!client.IsReady)
{
// Connection failed, report error
Console.Error.WriteLine(client.LastCrmException?.Message ?? client.LastCrmError);
}
else
{
// Connection success
// TODO Add your code here
var qry = new QueryExpression("account");
qry.ColumnSet = new ColumnSet(true);
var results = client.RetrieveMultiple(qry);
Console.WriteLine("Connection Succesfull!");
}
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
}
}
}
public class MichelOverrideExampleHookImplementation : IOverrideAuthHookWrapper
{
// In memory cache of access tokens
Dictionary<string, AuthenticationResult> accessTokens = new Dictionary<string, Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationResult>();
public void AddAccessToken(Uri orgUri, Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationResult accessToken)
{
// Access tokens can be matched on the hostname,
// different endpoints in the same organization can use the same access token
accessTokens[orgUri.Host] = accessToken;
}
public string GetAuthToken(Uri connectedUri)
{
// Check if you have an access token for this host
if (accessTokens.ContainsKey(connectedUri.Host) && accessTokens[connectedUri.Host].ExpiresOn > DateTime.Now)
{
return accessTokens[connectedUri.Host].AccessToken;
}
else
{
accessTokens[connectedUri.Host] = GetAccessTokenFromAzureAD(connectedUri);
}
return null;
}
public static AuthenticationResult GetAccessTokenFromAzureAD(Uri orgUrl,bool usePrompt = false)
{
string resource = "https://myorg.crm6.dynamics.com";
AuthenticationParameters ap = AuthenticationParameters.CreateFromResourceUrlAsync(
new Uri("https://myorg.crm6.dynamics.com/api/data/")).Result;
String authorityUrl = ap.Authority;
String resourceUrl = ap.Resource;
// TODO Substitute your correct CRM root service address,
// TODO Substitute your app registration values that can be obtained after you
// register the app in Active Directory on the Microsoft Azure portal.
string clientId = "120e36b3-0d1a-4596-a0d4-b31eb384607e";
string redirectUrl = "app://myredirecturl";
var userCred = new UserCredential("user@myorg.com", "password");
// Authenticate the registered application with Azure Active Directory.
//Previous authority urls: https://login.windows.net/common
AuthenticationContext authContext = new AuthenticationContext(authorityUrl, false);
AuthenticationResult result = null;
if (usePrompt)
{
result = authContext.AcquireToken(resource, clientId, new Uri(redirectUrl));
}
else
{
result = authContext.AcquireToken(resourceUrl, clientId, userCred);
}
return result;
}
答案 0 :(得分:0)
在PingFed中定义连接时(从以上代码定义为clientId =“ 120e36b3-0d1a-4596-a0d4-b31eb384607e”),您需要配置连接类型-浏览器SSO配置文件WS-Trust-您需要指定协议为SAML 2.0。