oAuth образец для ADFS Windows 2012 R2

Я установил ADFS, которая шла с Windows 2012 R2. Я зарегистрировал клиента с помощью Windows Powershell и получил client_id. Мне нужен образец, который работает на oAuth 2.0 с ADFS.

Большое спасибо

1 ответ

Решение

Я новичок в ADFS и не знаю, является ли мое решение лучшим, даже я не уверен, что оно правильное, но оно сработало для меня. Во всяком случае, на всякий случай, я поделюсь этим.

Основываясь на этом посте, вот мой пользовательский клиент для ADFS, использующий OAuth2. Мой код для приложения MVC4, использующего 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);
        }
    }

Обратите внимание на redirectUri, потому что он должен быть тем же, что вы зарегистрировали в ADFS.

Также я написал небольшой проект веб-API, основанный на публикации Витторио, для получения информации о пользователе.

Надеюсь, поможет.

Другие вопросы по тегам