.AddOAuth получить access_token из нестандартного ответа TokenEndpoint

Я добавил аутентификацию, как это

    services.AddAuthentication()
                .AddOAuth("external", "External Login", options =>
                {
                    options.ClientId = "external_id";
                    options.ClientSecret = "external_secret";
                    options.CallbackPath = new PathString("/signin-external");

                    options.AuthorizationEndpoint = "https://external.com/open-apis/authen/v1/index?app_id=external_id&redirect_uri=" + WebUtility.UrlEncode("https://myapp.com/signin-external");
                    options.TokenEndpoint = "https://external.com/open-apis/authen/v1/access_token";
                    options.UserInformationEndpoint = "https://external.com/open-apis/authen/v1/user_info";

                    options.BackchannelHttpHandler = new ExternalAuthorizingHandler(new HttpClientHandler(), options);

                    options.Events = new OAuthEvents
                    {
                        // never called
                        OnCreatingTicket = async context =>
                        {
                            var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
                            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);

                            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                            var response = await context.Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, context.HttpContext.RequestAborted);
                            response.EnsureSuccessStatusCode();

                            var user = JsonDocument.Parse(await response.Content.ReadAsStringAsync());

                            //context.HttpContext.Response.Cookies.Append("token", context.AccessToken);

                            context.RunClaimActions(user.RootElement);
                        }
                    };
                });

ExternalAuthorizingHandler.cs

public class ExternalAuthorizingHandler : DelegatingHandler
    {
        private readonly OAuthOptions options;
        public ExternalAuthorizingHandler(HttpMessageHandler inner, OAuthOptions options) : base(inner)
        {
            this.options = options;
        }

        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if (request.RequestUri == new Uri(options.TokenEndpoint))
            {
                string appendData = $"app_id={options.ClientId}&app_secret={options.ClientSecret}&";
                var content = request.Content.ReadAsStringAsync().Result;
                var cntn = QueryHelpers.ParseQuery(appendData + content);

                var dict = new Dictionary<string, string>();
                foreach (var c in cntn)
                {
                        dict.Add(c.Key, c.Value[0]);
                }
                string newContent = JsonConvert.SerializeObject(dict);

                request.Content = new StringContent(newContent, System.Text.Encoding.UTF8, "application/json");
            }
            return base.SendAsync(request, cancellationToken);
        }
    }

этот код может работать до тех пор, пока я не получу код авторизации и не перенаправлю на tokenEndpoint

но после выполнения SendAsync я получаю ошибку

Я не знаю, является ли SendAsync успешным или нет, но если это успех, то ответ от tokenEndpoint будет выглядеть так:

{
    "code": 0,
    "data": {
        "access_token": "u-D8kcSIGdlwQCySfgiEbrNc",
        "en_name": "John Doe",
        "expires_in": 6900,
        "name": "John Doe",
        "open_id": "ou_bace1bf309f5c8ad196019e63725e7ce",
        "refresh_expires_in": 2591700,
        "refresh_token": "ur-jFRCmumR5nqhanRVH3SGdf",
        "tenant_key": "2ede6044ee4f1656",
        "token_type": "Bearer",
        "union_id": "on_13c0df6770171400f042f536660ca8be"
    },
    "msg": "success"
}
  1. что за ошибка и как с ней бороться? это связано с куками?
  2. как проверить SendAsync результат
  3. как обрабатывать ответ, как указано выше, из AddOAuth вариантов

спасибо


person noob    schedule 29.12.2020    source источник


Ответы (1)


В ASP.NET Core не следует использовать AddOAuth, вместо этого рекомендуется использовать AddOpenIDConnect.

Что касается неизвестного местоположения, возможно, это вопрос может дать вам некоторую подсказку.

person Tore Nestenius    schedule 29.12.2020