在ASP.NET Web Api中存储OAuth访问令牌

时间:2018-04-04 09:34:42

标签: c# asp.net cookies oauth token

我目前正在asp.net中构建一个API(我并不完全容易与之相关的语言),而且我正在处理身份验证中的一些问题。

我使用OAuth令牌为用户提供数据访问权限,用户在提供正确的电子邮件和密码时获取令牌。到目前为止,非常好。

我需要将令牌存储在某处,经过几天的研究,我发现如果配置正确,cookie是一个很好的解决方案。事情是:如果我将令牌存储在cookie中,它将被暴露,对吧?一个人实际上可以看到它,这不是我的意图,或者至少,只是能够看到它的哈希值。

我还阅读了有关XSS和CSRF攻击的内容,为此,我需要将其设置为HttpOnly并仅限制为HTTPS连接。

我已经阅读了大量的教程,但实际上并没有实现。 我错过了什么?饼干根本不安全吗?有没有更好的地方存放? 任何帮助都是apreciated

这是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
    }
}

0 个答案:

没有答案