Хранение токена доступа OAuth в веб-API ASP.NET

В настоящее время я создаю API на asp.net (язык, который мне не совсем удобен), и я имею дело с некоторыми проблемами при аутентификации.

Я использую токены OAuth, чтобы предоставить пользователю доступ к данным, и пользователь получает токен в тот момент, когда он дает правильный адрес электронной почты и пароль. Все идет нормально.

Мне нужно где-то хранить токен, и после нескольких дней исследований я обнаружил, что файлы cookie - хорошее решение, если они настроены правильно. Дело в том, что если я сохраню токен в файле cookie, он будет открыт, верно? Человек действительно может это увидеть, а я не хотел этого, или, по крайней мере, просто иметь возможность увидеть его хеш.

Я также читал об атаках XSS и CSRF, и для этого мне нужно установить его на HttpOnly и ограничить только HTTPS-соединениями.

Я прочитал кучу руководств, но ни одно из них не помогло. Что мне не хватает? Файлы cookie вообще небезопасны? Есть ли лучшее место для его хранения? Любая помощь приветствуется

Вот файл StartupAuth.cs:

using System;
using Microsoft.AspNet.Identity;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Cors.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OAuth;
using Owin;
using util_api.Providers;

namespace util_api
{
public partial class Startup
{
    public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }

    public static string PublicClientId { get; private set; }

    // Para obter mais informações sobre a autenticação de configuração, visite https://go.microsoft.com/fwlink/?LinkId=301864
    public void ConfigureAuth(IAppBuilder app)
    {
        // Habilite o aplicativo para usar um cookie que armazena informações do usuário conectado
        // e um cookie que armazena informações temporárias sobre um usuário que faz login em um provedor de login de terceiros

        // Configure o aplicativo para fluxo com base em OAuth
        PublicClientId = "self";

        OAuthOptions = new OAuthAuthorizationServerOptions
        {

            TokenEndpointPath = new PathString("/Token"),
            Provider = new OAuthProvider(),
            AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),

            // Em modo de produção, defina AllowInsecureHttp = false
            AllowInsecureHttp = true

        };

        // Habilite o aplicativo para usar tokens portadores na autenticação de usuários

        app.UseOAuthAuthorizationServer(OAuthOptions);
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

    }
  }
}

И OAuthProvider.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OAuth;
using util_api.Models;
using util_api.Services;


namespace util_api.Providers
{
public class OAuthProvider : OAuthAuthorizationServerProvider
{
    #region[GrantResourceOwnerCredentials]
    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {

        return Task.Factory.StartNew(() =>
        {
            var userName = context.UserName;
            var password = context.Password;
            var userService = new UserService(); // our created one
            var user = userService.ValidateUser(userName, password);
            if (user != null)
            {
                var claims = new List<Claim>()
                {
                    new Claim(ClaimTypes.Sid, Convert.ToString(user.ID)),
                    new Claim(ClaimTypes.Name, user.NAME),
                    new Claim(ClaimTypes.Email, user.EMAIL)
                };
                ClaimsIdentity oAuthIdentity = new ClaimsIdentity(claims,
                            Startup.OAuthOptions.AuthenticationType);

                var properties = CreateProperties(user.ID.ToString());
                var ticket = new AuthenticationTicket(oAuthIdentity, properties);
                context.Validated(ticket);
            }
            else
            {
                context.SetError("invalid_grant", "O endereço eletrónico ou palavra passe estão incorretos. Por favor, verifique as suas credenciais.");
            }
        });
    }
    #endregion

    #region[ValidateClientAuthentication]
    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        if (context.ClientId == null)
            context.Validated();

        return Task.FromResult<object>(null);
    }
    #endregion

    #region[TokenEndpoint]
    public override Task TokenEndpoint(OAuthTokenEndpointContext context)
    {
        foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
        {
            context.AdditionalResponseParameters.Add(property.Key, property.Value);
        }

        return Task.FromResult<object>(null);
    }
    #endregion

    #region[CreateProperties]
    public static AuthenticationProperties CreateProperties(string id)
    {
        IDictionary<string, string> data = new Dictionary<string, string>
        {
            { "id", id }
        };
        return new AuthenticationProperties(data);
    }
    #endregion
    }
}

если вы храните файл cookie, пользователи могут его видеть. пользователи могут видеть все, что передается между браузером и вашим сервером. вы разместили код, но не описали, какая у вас проблема / вопрос относительно этого кода.

Robert Levy 04.04.2018 17:05

@RobertLevy Извини, я плохо себя объясняю! Это код, который у меня есть прямо сейчас, который генерирует токен. Когда я вызываю эту конечную точку - localhost: 56758 / api / Token - я получаю токен именно таким, каким он должен был быть. Моя проблема / вопрос в том, как сохранить его непосредственно в файле cookie в момент вызова этой конечной точки. Или, если существует лучший способ / место для его хранения. Надеюсь, это прояснилось :)

LuisMorais 04.04.2018 17:53
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
660
0

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