Nancy Stateless Auth Config不接受IPrincpal

时间:2017-02-24 03:44:06

标签: c# authentication nancy

我正在尝试使用nancy为我的API实现无状态身份验证,但在sample stateless project之后我遇到了问题。当我创建StatelessAuthenticationConfiguration

    new StatelessAuthenticationConfiguration(nancyContext =>
    {
        var apiKey = JsonConvert.DeserializeObject<ApiKeyModel>(nancyContext.Request.Body.AsString()).ApiKey;
        return GetUserFromApiKey(apiKey);
    });

它给我一个关于无法隐式转换IPrincipal

的错误
    internal static IPrincipal GetUserFromApiKey(string apiKey)
    {
        using (var con = GetConnection())
        {
            using (var cmd = con.CreateCommand())
            {
                Console.WriteLine($"Key: {apiKey}");
                cmd.CommandText = $"SELECT username FROM apiKeys WHERE apiKey = {apiKey}";
                string username = (string)cmd.ExecuteScalar();

                if (string.IsNullOrWhiteSpace(username))
                    return null;
                else
                    return new ClaimsPrincipal(new GenericIdentity(username, "stateless"));//new UserModel(username);
            }
        }
    }

我给它。我已尝试转换为IUserIdentity,甚至使用我自己的UserModel

class UserModel : IUserIdentity
{
    public string UserName { get; }

    public IEnumerable<string> Claims { get; }

    public UserModel(string username)
    {
        UserName = Uri.EscapeDataString(username);
    }


}

实施IUserIdentity。这不会产生错误,但用户不会通过身份验证。用户仍然无法访问我的secure module

public class APIModule : NancyModule
{
    public APIModule() : base("/api")
    {
        StatelessAuthentication.Enable(this, Aoba.StatelessConfig);
        this.RequiresAuthentication();

        Post["/"] = _ =>
        {
            Console.WriteLine(Context.CurrentUser.IsAuthenticated());
            return new Response { StatusCode = HttpStatusCode.OK };
        };
    }
}

尽管已经过了所有必需的验证并且具有正确的apiKey。从我的测试来看,似乎用户永远不会被分配到南希上下文。正在使用配置,并且通过apiKey获取用户,但它永远不会被设置。有什么我想念的吗?如果您想进一步检查项目,可以找到完整项目here

1 个答案:

答案 0 :(得分:0)

原来我的查询错误是从apiKey获取用户。以下是更正,现在一切都按预期工作。

    internal static UserModel GetUserFromApiKey(string apiKey)
    {
        using (var con = GetConnection())
        {
            using (var cmd = con.CreateCommand())
            {
                Console.WriteLine($"Key: {apiKey}");
                cmd.CommandText = $"SELECT username FROM apiKeys WHERE apikey = '{apiKey}'";
                using (var reader = cmd.ExecuteReader())
                {
                    if (!reader.HasRows)
                        return null;
                    reader.Read();
                    string username = reader.GetString(0);
                    if (string.IsNullOrWhiteSpace(username))
                        return null;
                    else
                        return new UserModel(username);
                }
            }
        }
    }