使用JSON Web令牌在MVC应用程序中验证用户

时间:2015-03-04 22:42:55

标签: c# asp.net-mvc authentication jwt

我有一个遗留应用程序,我希望在新的asp.net MVC应用程序中生成会话。我试图将JSON Web令牌传递给MVC应用程序以验证用户。我在大多数情况下工作,但它需要一些额外的代码来让用户登录(使用Request.GetOwinContext()。ctx.Authentication.SignIn)。它让我怀疑我是否走正确的道路。

根据我的阅读,我认为我应该能够使用ValidateToken方法创建的ClaimsPrincipal对象将用户签名到应用程序中。

我的问题:

  1. ValidateToken创建的ClaimsIdentity实例将Authentication Type设置为Federated。要将用户签入MVC应用程序,我需要将身份验证类型设置为Cookies(我认为)。为此,我创建了一个新的ClaimsIdentity实例,该实例基于ValidateToken创建的实例,然后将ApplicationCookie作为身份验证类型传递给构造函数。是否有必要这样做,有没有办法在原始的ClaimsIdentity实例上更改身份验证类型而不创建新的?
  2. 我无法通过ValidateToken方法自动设置name属性。 SignIn方法似乎要求设置。为了解决这个问题,我通过从ValidateToken(ident2.AddClaim(new Claim(ClaimTypes.Name, myIdentity.FindFirstValue("Name")));)创建的ClaimsIdentity实例中提取名称声明来明确设置它。我是否可以传递JWT的有效负载,并自动映射到此属性?
  3. 或者一般来说这是完成身份验证的错误方法吗?

    我的JWT的有效载荷声明集如下所示:

    {
      "iss": "http://oldapp.testing.com",
      "aud": "http://newapp.testing.com",
      "sub": "99239",
      "iat": 1425507035,
      "exp": 1425507065,
      "name": "First Last",
      "role": [
        "Admin"
      ]
    

    以及处理它的C#代码:

            JwtSecurityToken tokenReceived = new JwtSecurityToken(token);
    
            JwtSecurityTokenHandler recipientTokenHandler = new JwtSecurityTokenHandler();
    
            byte[] keyBytes = Encoding.UTF8.GetBytes("someTestSecretKeyForTestingThis");
            if (keyBytes.Length < 64 && tokenReceived.SignatureAlgorithm == "HS256")
            {
                Array.Resize(ref keyBytes, 64);
            }
    
    
            TokenValidationParameters validationParameters = new TokenValidationParameters()
            {
                ValidIssuer = "http://oldapp.testing.com",
                ValidAudience = "http://newapp.testing.com",
                IssuerSigningToken = new BinarySecretSecurityToken(keyBytes)
            };
    
            try
            {
                SecurityToken validatedToken;
                var principal = recipientTokenHandler.ValidateToken(token, validationParameters, out validatedToken);
    
                // Pull out the ClaimIdentity created by ValidateToken
                var myIdentity = principal.Identities.FirstOrDefault();
    
                //
                // Copy ClaimIdentity created by the ValidateToken method and change the Authentication
                // type from Federated to Cookie
                //
                // Is there a better way to do this???
                //
                var ident2 = new ClaimsIdentity(myIdentity.Claims, DefaultAuthenticationTypes.ApplicationCookie);
    
                //
                // Make sure the Name claim is set correctly so that the SignIn method will work
                //
                // Why isn't the Name claim set automatically???
                //
                ident2.AddClaim(new Claim(ClaimTypes.Name, myIdentity.FindFirstValue("Name")));
    
                // Sign the user in
                var ctx = Request.GetOwinContext();
                var authManager = ctx.Authentication;
                authManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
                authManager.SignIn(ident2);
    
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("Exception :" + ex.Message);
    

0 个答案:

没有答案