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





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