Question

I have installed ADFS that came with Windows 2012 R2. I have registered the client using Windows Powershell and obtained the client_id. I need a sample that works on oAuth 2.0 with ADFS.

Many thanks

Was it helpful?

Solution

I'm new with ADFS and I don't know if my solution is the best, even I'm not sure if it is correct, but it worked for me. Anyway, just in case, I'll share it.

Based on this post, here is my custom client for ADFS using OAuth2. My code is for MVC4 application using DotNetOpenAuth.

public class AuthServiceOAuth2Client : OAuth2Client
{

    #region Constants and Fields

    /// <summary>
    /// The authorization endpoint.
    /// </summary>
    private const string AuthorizationEndpoint = "https://your_adfs/adfs/oauth2/authorize";

    /// <summary>
    /// The token endpoint.
    /// </summary>
    private const string TokenEndpoint = "https://your_adfs/adfs/oauth2/token";

    /// <summary>
    /// The _app id.
    /// </summary>
    private readonly string _clientId;

    /// <summary>
    /// The _app secret.
    /// </summary>
    private readonly string _clientSecret;

    #endregion


    public AuthServiceOAuth2Client(string clientId, string clientSecret)
        : base("ADFS")
    {
        if (string.IsNullOrWhiteSpace(clientId)) throw new ArgumentNullException("clientId");
        if (string.IsNullOrWhiteSpace(clientSecret)) throw new ArgumentNullException("clientSecret");

        this._clientId = clientId;
        this._clientSecret = clientSecret;
    }

    protected override Uri GetServiceLoginUrl(Uri returnUrl)
    {
        StringBuilder serviceUrl = new StringBuilder();

        serviceUrl.AppendFormat("{0}?grant_type=authorization_code", AuthorizationEndpoint);

        serviceUrl.AppendFormat("&redirect_uri={0}", returnUrl.ToString());
        serviceUrl.Append("&response_type=code");
        serviceUrl.AppendFormat("&client_id={0}", _clientId);
        serviceUrl.AppendFormat("&resource={0}", "your_resource");

        return new Uri(serviceUrl.ToString());
    }

    protected override IDictionary<string, string> GetUserData(string accessToken)
    {
        // do stuff
        return new Dictionary<String, String>();
    }

    protected override string QueryAccessToken(Uri returnUrl, string authorizationCode)
    {
        StringBuilder postData = new StringBuilder();
        postData.AppendFormat("client_id={0}", this._clientId);
        postData.AppendFormat("&redirect_uri={0}", HttpUtility.UrlEncode(returnUrl.ToString()));
        postData.AppendFormat("&client_secret={0}", this._clientSecret);
        postData.AppendFormat("&grant_type={0}", "authorization_code");
        postData.AppendFormat("&code={0}", authorizationCode);

        string response = "";
        string accessToken = "";

        var webRequest = (HttpWebRequest)WebRequest.Create(TokenEndpoint);

        webRequest.Method = "POST";
        webRequest.ContentType = "application/x-www-form-urlencoded";

        try
        {

            using (Stream s = webRequest.GetRequestStream())
            {
                using (StreamWriter sw = new StreamWriter(s))
                    sw.Write(postData.ToString());
            }

            using (WebResponse webResponse = webRequest.GetResponse())
            {
                using (StreamReader reader = new StreamReader(webResponse.GetResponseStream()))
                {
                    response = reader.ReadToEnd();
                }
            }

            var json = JObject.Parse(response);
            accessToken = (string)json["access_token"];
        }
        catch (Exception ex)
        {
            return null;
        }

        return accessToken;
    }

    public override AuthenticationResult VerifyAuthentication(HttpContextBase context, Uri returnPageUrl)
    {
        string code = context.Request.QueryString["code"];
        if (string.IsNullOrEmpty(code))
        {
            return AuthenticationResult.Failed;
        }

        string accessToken = this.QueryAccessToken(returnPageUrl, code);
        if (accessToken == null)
        {
            return AuthenticationResult.Failed;
        }

        IDictionary<string, string> userData = this.GetUserData(accessToken);
        if (userData == null)
        {
            return AuthenticationResult.Failed;
        }

        string id = userData["id"];
        string name;

        // Some oAuth providers do not return value for the 'username' attribute. 
        // In that case, try the 'name' attribute. If it's still unavailable, fall back to 'id'
        if (!userData.TryGetValue("username", out name) && !userData.TryGetValue("name", out name))
        {
            name = id;
        }

        // add the access token to the user data dictionary just in case page developers want to use it
        userData["accesstoken"] = accessToken;

        return new AuthenticationResult(
            isSuccessful: true, provider: this.ProviderName, providerUserId: id, userName: name, extraData: userData);
    }
}

Pay attention on the redirectUri because it should be the same you registered on ADFS.

I have also coded a little Web API project based on the Vittorio's post to retrieve the user info.

Hope it helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top