C# Azure移动应用程序-自定义身份验证-无法登录

C# Azure移动应用程序-自定义身份验证-无法登录,c#,asp.net,authentication,xamarin.forms,azure-mobile-services,C#,Asp.net,Authentication,Xamarin.forms,Azure Mobile Services,我在一个Xamarin Forms移动应用程序中工作,有.NET背景。我尽可能地跟随导游。但是这些都是不完整的,并且没有完整的自定义身份验证示例。我终于达到了一个我现在不知道如何前进的地步。我无法登录 在客户端获得LoginAsync的响应后,我收到此错误: user = await TodoItemManager.DefaultManager.CurrentClient.LoginAsync("CustomAuth", credentials); 这就是错误: ex {"Objec

我在一个Xamarin Forms移动应用程序中工作,有.NET背景。我尽可能地跟随导游。但是这些都是不完整的,并且没有完整的自定义身份验证示例。我终于达到了一个我现在不知道如何前进的地步。我无法登录

在客户端获得LoginAsync的响应后,我收到此错误:

     user = await TodoItemManager.DefaultManager.CurrentClient.LoginAsync("CustomAuth", credentials);
这就是错误:

ex {"Object reference not set to an instance of an object."} System.Exception {System.NullReferenceException}
如果我使用像Google+这样的默认提供程序,那么它的工作就完美了。所以我认为问题出在后端。但我不知道我做错了什么。我将代码循环了好几次,看起来很好。 我试着调试服务器端,直到它到达客户端,我才发现任何错误

我做错了什么

这是我在服务器端的代码

    public IHttpActionResult Post(LoginRequest loginRequest)
    {
        if (isValidAssertion(loginRequest.username, loginRequest.password)) // user-defined function, checks against a database
        {
            JwtSecurityToken token = GetAuthenticationTokenForUser(loginRequest.username);

            return Ok(new
            {
                AuthenticationToken = token.RawData,
                User = new { UserId = loginRequest.username }
            });
        }
        else // user assertion was not valid
        {
            return Unauthorized();
        }
    }
辅助功能:

    private bool isValidAssertion(string username, string password)
    {
        AspNetUsers AspNetUser = db.AspNetUsers.SingleOrDefault(x => x.UserName.ToLower() == username.ToLower());
        return AspNetUser != null && VerifyHashedPassword(AspNetUser.PasswordHash, password);
    }

    private JwtSecurityToken GetAuthenticationTokenForUser(string username)
    {
        var claims = new Claim[]
        {
            new Claim(JwtRegisteredClaimNames.Sub, username)
        };

        string signingKey = "123456789123456789...";//Environment.GetEnvironmentVariable("WEBSITE_AUTH_SIGNING_KEY");
        string audience = "https://todo.azurewebsites.net/"; // audience must match the url of the site
        string issuer = "https://todo.azurewebsites.net/"; // audience must match the url of the site

        JwtSecurityToken token = AppServiceLoginHandler.CreateToken(
            claims,
            signingKey,
            audience,
            issuer,
            TimeSpan.FromHours(24)
        );

        return token;
    }
在Startup类中,我添加了:

        config.Routes.MapHttpRoute("CustomAuth", ".auth/login/CustomAuth", new { controller = "CustomAuth" });
这是我在客户端的代码:

    public async Task<bool> Authenticate()
    {
        string username = "todo@gmail.com";
        string password = "todo";

        string message = string.Empty;
        var success = false;
        var credentials = new JObject
        {
            ["username"] = username,
            ["password"] = password
        };
        try
        {
            user = await TodoItemManager.DefaultManager.CurrentClient.LoginAsync("CustomAuth", credentials);
            if (user != null)
            {
                success = true;
                message = string.Format("You are now signed-in as {0}.", user.UserId);
            }
        }
        catch (Exception ex)
        {
            message = string.Format("Authentication Failed: {0}", ex.Message);
        }
        await new MessageDialog(message, "Sign-in result").ShowAsync();
        return success;
    }

看起来服务器的响应是错误的。从一个有效的响应来看,它应该是:

{
    "user": "your-user-id",
    "authenticationToken": "the-jwt"
}

更正服务器代码中的响应,看看是否有帮助。

当您通过邮递员使用用户名/密码发布时,响应是什么样子的?另外,在文章之后,client.CurrentUser对象是什么样子的?Id和MobileServiceAuthenticationToken设置好了吗?最后,如果您使用Postman向您的.auth/login/CustomAuth发送邮件,然后执行GET/tables/foo,并将X-ZUMO-auth头设置为您的身份验证令牌,是否有效?在使用Postman的第一个场景中,我会获得类似于:{“MobileServiceAuthenticationToken”:“ey1234…”,“UserId”:“sid:1234…”的回复另一方面,client.CurrentUser设置为null并引发异常。在第二种情况下,使用GET获取表中的2行。能否确保TodoItemManager.DefaultManager.CurrentClient不为null?噢,天哪,就是这样。我以前试过这些话,但我失败了,但现在我知道为什么了。这个错误是大小写的问题。名称必须是“用户”、“用户ID”和“authenticationToken”。就是这样。多谢各位。
{
    "user": "your-user-id",
    "authenticationToken": "the-jwt"
}