使用ASP.NET标识扩展Azure移动服务的功能

时间:2014-03-26 14:22:12

标签: security authentication azure asp.net-identity azure-mobile-services

我有一个.Net移动服务后端(即不是JavaScript),它开箱即用,支持通过windows azure门户与常见的身份提供商(Facebook,Twitter等)进行身份验证。但是,我希望用户能够创建自己的用户名/密码帐户,因为他们可以使用ASP.NET身份的ASP.NET Web Api实现(使用AccountController)。

问题是这是否可能,如果是这样,实现它的最佳方法是什么?

我的第一个想法是从模板ASP.NET MVC Web Api项目中复制相应的类(AccountController,Startup.Auth,ApplicationOAuthProvider等),并添加对Microsoft.AspNet.Identity.EntityFramework和System.Web的引用。 .MVC但我不知道这会产生什么影响。如果它有效,我将刚刚通过门户网站" Identity"来控制身份验证逻辑。不再有任何影响?

另一种选择是简单地从Web Api项目开始,并将移动服务功能添加到该项目中(虽然我无法看到如何在没有MVC的情况下创建Web Api项目,但这是一个不同的问题)。

感谢您的帮助。

2014年4月11日更新

最后,我们决定管理自己的用户名和密码并生成JWT令牌,以便客​​户端可以使用标准的IMobileServiceClient。为此,我们使用了两种资源。第一个来自代码的喜悦:

http://www.thejoyofcode.com/Exploring_custom_identity_in_Mobile_Services_Day_12_.aspx

,第二个来自内容大师:

http://www.contentmaster.com/azure/creating-a-jwt-token-to-access-windows-azure-mobile-services/

虽然我们根据此移动服务团队博客文章对代码进行了一些小的更改:

[没有足够的声望点可以添加第三个链接,所以只需谷歌"更改天青 - 移动服务-jwt-token"]

所以这里是代码,如果有用的话。 (使用JwtSecurityTokenHandler编写实现可能更好,但这适用于我们)

 public static string GetSecurityToken(TimeSpan periodBeforeExpires, string aud, string userId, string masterKey)
    {
        var now = DateTime.UtcNow;
        var utc0 = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
        var payload = new
                      {
                          exp = (int)now.Add(periodBeforeExpires).Subtract(utc0).TotalSeconds,
                          iss = "urn:microsoft:windows-azure:zumo",
                          ver = 2,
                          aud = "urn:microsoft:windows-azure:zumo",
                          uid = userId
                      };

        var keyBytes = Encoding.UTF8.GetBytes(masterKey + "JWTSig");
        var segments = new List<string>();

        //kid changed to a string
        var header = new { alg = "HS256", typ = "JWT", kid = "0" };
        byte[] headerBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header, Formatting.None));
        byte[] payloadBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload, Formatting.None));
        segments.Add(Base64UrlEncode(headerBytes));
        segments.Add(Base64UrlEncode(payloadBytes));
        var stringToSign = string.Join(".", segments.ToArray());
        var bytesToSign = Encoding.UTF8.GetBytes(stringToSign);
        SHA256Managed hash = new SHA256Managed();
        byte[] signingBytes = hash.ComputeHash(keyBytes);
        var sha = new HMACSHA256(signingBytes);
        byte[] signature = sha.ComputeHash(bytesToSign);
        segments.Add(Base64UrlEncode(signature));
        return string.Join(".", segments.ToArray());
    }

  // from JWT spec
    private static string Base64UrlEncode(byte[] input)
    {
        var output = Convert.ToBase64String(input);
        output = output.Split('=')[0]; // Remove any trailing '='s
        output = output.Replace('+', '-'); // 62nd char of encoding
        output = output.Replace('/', '_'); // 63rd char of encoding
        return output;
    }

1 个答案:

答案 0 :(得分:1)

这是可能的但不是我们想要的那么简单(我们有一个改进它的错误)。一般来说,它归结为您可以将内容注入OWIN管道,包括 auth提供程序。

如果您熟悉OWIN管道和ASP.NET身份框架,那么这里大概是您做的:

1)创建自己的OWIN App Builder,为.NET后端设置OWIN管道。

2)使用依赖注入引擎注册App Builder,该引擎将作为初始化的一部分进行调用。

以下是它的外观(使用nuget.org最新的NuGets):

https://gist.github.com/HenrikFrystykNielsen/9835526

它不会自动陷入&#34;登录&#34;控制器我们有一个工作项来启用它,但我认为如果你小心,它应该工作。

顺便说一下,您可以从Filip W的博客中找到一些好消息:http://www.strathweb.com/2014/02/running-owin-pipeline-new-net-azure-mobile-services/

希望这有帮助!

的Henrik