Reputation: 13
I have tried to get a SAML token from ADFS to pull data from on-premises CRM (non-sdk), but I don't know how..I think I need to make a SOAP request to ADFS to get a SAML token by using postasync method, and then I think I need to put the token in a http header like below to pull data from CRM.
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", TOKEN);
https://community.dynamics.com/crm/f/microsoft-dynamics-crm-forum/255985/crm2016-afds-authentication
https://gist.github.com/jlattimer/7b0ee146badfc57fc9c9
I have read those three links above (and other stuff), and tried them but it seems like the first two work only for sdk, not non-sdk. And, the github stuff didn't work for me, either. And I wonder if there is another way to generate a SOAP request instead of typing in everything like in the third link.
Upvotes: 0
Views: 2271
Reputation: 2122
This code will get you the SAML Token for SAP Odata Services in C#
protected HttpClient Client
{
get
{
if (client == null)
{
handler = new HttpClientHandler();
handler.Credentials = new NetworkCredential(username, password);
handler.AllowAutoRedirect = false;
handler.CookieContainer = cookies;
handler.UseCookies = true;
client = new HttpClient(handler);
client.MaxResponseContentBufferSize = 9999999;
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
client.DefaultRequestHeaders.Add("Connection", "Keep-Alive");
client.DefaultRequestHeaders.ExpectContinue = false;
}
return client;
}
}
public String GetSAML()
{
if (client != null)
{
client = null;
}
String text = "";
String SAMLTokenBase64String="";
String urlRelayParty = "Your_Relay_party_identifier";
string url = String.Format("{0}?loginToRp={1}", "https://***yourdomainforstsoradfs*****.com/adfs/ls/IdpInitiatedSignOn.aspx", HttpUtility.UrlEncode(urlRelayParty));
do
{
result = Client.GetAsync(url).GetAwaiter().GetResult();
text = result.Content.ReadAsStringAsync().GetAwaiter().GetResult();
IEnumerable<string> values;
if (result.Headers.TryGetValues("location", out values))
{
foreach (string s in values)
{
if (s.StartsWith("/"))
{
url = url.Substring(0, url.IndexOf("/adfs/ls")) + s;
}
else
url = s;
}
}
else
{
url = "";
}
}
while (!String.IsNullOrEmpty(url));
Regex reg = new Regex("SAMLResponse\\W+value\\=\\\"([^\\\"]+)\\\"");
MatchCollection matches = reg.Matches(text);
foreach (Match m in matches)
{
SAMLTokenBase64String = m.Groups[1].Value;
}
if (SAMLTokenBase64String != null && SAMLTokenBase64String.Trim().Length > 0)
{
SB("STS Login Successfull for " + urlRelayParty);
return SAMLTokenBase64String;
}
SB("STS Login Failed for " + urlRelayParty);
return "";
}
Upvotes: 0
Reputation: 46720
ADFS is an Identity Provider (IDP) and implements:
Your client has to implement one of these three protocols.
You can't use SOAP.
For OpenID Connect (OIDC), you can use a REST API but that gives you a JWT, not a SAML token.
Once you have the access token via OIDC, you add it as ("Bearer", TOKEN) as you describe.
Upvotes: 1
Reputation: 11
There is two ways, which I know. In both ways you need to add your app as RPT to ADFS. Check this: https://learn.microsoft.com/ru-ru/windows-server/identity/ad-fs/operations/create-a-relying-party-trust Don't forget to enable saml protocol and set assertion consumer endpoint.
Solution one:
Just redirect all unauthorized users to https://your.adfs.instance/adfs/ls/IDpInitiatedSignon.aspx They will provide credentials and then will be asked to choose app for redirect. If you will specify app using Relay state in url there will be no choice. After that ADFS will send SAML response to endpoint, which was specified for RPT. If you use .NET, you can use WS-Fed module, which will automate this dataflow.
Solution two:
You can do the same on your backend. Thisis realization for .NET: https://blogs.msdn.microsoft.com/rodneyviana/2014/04/21/how-to-get-a-saml-protocol-response-from-adfs-using-c/
Also, you can make direct calls to ADFS, it'sa bit more native, but I don't guarantee that it will be SAML tokens. Here is example: Authentication in C# with Active Directory
UPD. I read your question again and not sure, that it is what you need.
Upvotes: 0