Search code examples
restasp.net-web-apiclaims-based-identityadfsclaims

Claims transformation in ADFS 3.0 by making a call to REST API


We have a ASP.NET Web API (REST service) in our enterprise that gives us the list of coarse-grained claims for a user that we want to inject into the adfs token before passing the token onto the application. Does anyone know if making a rest call is possible using the Custom attribute store (by passing param's to the custom attribute store from the Claims rule language in ADFS 3.0) ?

Any help regarding this would be greatly appreciated!

Thanks,
Ady.


Solution

  • I'm able to make the REST call from the Custom Attribute store. For those who are still wondering about this can look at the below code.

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IdentityModel;
    
    using Microsoft.IdentityServer.ClaimsPolicy.Engine.AttributeStore;
    using System.Net.Http;
    using System.Net;
    
    namespace CustomAttributeStores
    {
        public class CoarseGrainClaimsAttributeStore : IAttributeStore
        {
            #region Private Members
    
            private string API_Server = "https://<Server Name>/API/";
    
            #endregion
    
            #region IAttributeStore Members
    
            public IAsyncResult BeginExecuteQuery(string query, string[] parameters, AsyncCallback callback, object state)
            {   
                string result = string.Empty;
    
                if (parameters == null)
                {
                    throw new AttributeStoreQueryFormatException("No query parameter.");
                }
    
                if (parameters.Length != 1)
                {
                    throw new AttributeStoreQueryFormatException("More than one query parameter.");
                }
    
                string userName = parameters[0];
    
                if (userName == null)
                {
                    throw new AttributeStoreQueryFormatException("Query parameter cannot be null.");
                }
    
                //Ignore SSL Cert Error
                //TODO: Need to set the SSL cert correctly for PROD Deployment
                ServicePointManager.ServerCertificateValidationCallback +=  (sender, cert, chain, sslPolicyErrors) => true;
    
                using (var client = new HttpClient())
                {
    
                    //The url can be passed as a query
                    string serviceUrl = API_Server  + "GetAdditionalClaim";
                    serviceUrl += "?userName=" + userName;
    
                    //Get the SAML token from the API
                    result = client
                                .GetAsync(serviceUrl)
                                .Result
                                .Content.ReadAsStringAsync().Result;
                    result = result.Replace("\"", "");
                }
    
                string[][] outputValues = new string[1][];
                outputValues[0] = new string[1];
                outputValues[0][0] = result;
    
                TypedAsyncResult<string[][]> asyncResult = new TypedAsyncResult<string[][]>(callback, state);
                asyncResult.Complete(outputValues, true);
                return asyncResult;
            }
    
            public string[][] EndExecuteQuery(IAsyncResult result)
            {
                return TypedAsyncResult<string[][]>.End(result);
            }
    
            public void Initialize(Dictionary<string, string> config)
            {
                // No initialization is required for this store.
            }
    
            #endregion
        }
    }