OWIN-在Auth Server返回承载令牌后,如何验证角色的承载令牌?

时间:2018-10-23 11:29:33

标签: c# asp.net-mvc oauth-2.0 jwt owin

我一直在与我们的MVC应用程序的安全性作斗争两个星期。我已经设置了一个授权服务器来生成供两个客户端MVC应用程序使用的令牌。但是,我现在正在生成令牌,并且它将令牌返回给客户端,但是在我检查索赔的地方,它返回false。

这是从Auth服务器生成令牌的代码:

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();

        User user = await userManager.FindAsync(context.UserName, context.Password);

        if (user == null)
        {
            context.SetError("invalid_grant", "The email address or password is incorrect.");
            return;
        }

        ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, OAuthDefaults.AuthenticationType);
        ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager, CookieAuthenticationDefaults.AuthenticationType);

        AuthenticationProperties properties = CreateProperties(context, user.UserName);
        AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
        context.Validated(ticket);
        context.Request.Context.Authentication.SignIn(cookiesIdentity);
    }

这将生成要发送给客户端的令牌,并在“ GenerateUserIdentityAsync”方法中,根据需要在“声明标识”上添加角色。

但是,当我在客户端上收到承载令牌并且不知道如何将其转换为本地ClaimIdentity时,我可以进行询问以获取对角色的访问权限。这是从Auth Server获取对资源服务器(客户端)的access_token的代码:

[HttpPost]
    [AllowAnonymous]
    //[ValidateAntiForgeryToken]
    public ActionResult SignIn(AccountViewModel account)
    {
        var getTokenUrl = $"{_settings.AuthServiceUrl}oauth2/token";

        HttpContent content = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair<string, string>("grant_type", "password"),
            new KeyValuePair<string, string>("username", account.Login.Email),
            new KeyValuePair<string, string>("password", account.Login.Password),
            new KeyValuePair<string, string>("client_id", _settings.AuthClientId)
        });
        using (var client = new HttpClient())
        {
            HttpResponseMessage result = client.PostAsync(getTokenUrl, content).Result;

            string resultContent = result.Content.ReadAsStringAsync().Result;
            var token = JsonConvert.DeserializeObject<Token>(resultContent);

            if (string.IsNullOrEmpty(token.access_token))
            {
                ViewBag.Error = "Incorrect Username or Password, Please try again!";
                return View("Login");
            }

            var options = new AuthenticationProperties
            {
                AllowRefresh = true,
                IsPersistent = true,
                ExpiresUtc = DateTime.UtcNow.AddSeconds(int.Parse(token.expires_in))
            }; 

            var claims = new[]
            {
                new Claim(ClaimTypes.Email, account.Login.Email),
                new Claim("AccessToken", $"Bearer {token.access_token}"),
            };

            var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
            Request.GetOwinContext().Authentication.SignIn(options, identity);

            if (identity.HasClaim(ClaimTypes.Role, "Admin"))
            {
                return RedirectToAction("Index", "Admin");
            }

            return RedirectToAction("Index", "Home");
        }
    }

我在JWT.io上检查了承载令牌,它的作用是:

  

{     “ nameid”:“ 1”,     “唯一名称”:[       “ admin@fsa.co.za”,       “管理员管理员”     ],     “ http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider”:“ ASP.NET身份”,     “ AspNet.Identity.SecurityStamp”:“ de9090f4-bddb-4baf-a62b-38ed0d6528fe”,     “角色”:[       “管理员”,       “管理员”     ],     “ UserId”:“ 1”,     “ sub”:“ admin@fsa.co.za”,     “电子邮件”:“ admin@fsa.co.za”,     “ Verified”:“ False”,     “ iss”:“ https://localhost:44318/”,     “ aud”:“ b77f169bd7bf4787b1aed11599861768”,     “ exp”:1540293963,     “ nbf”:1540292163   }

我的问题是,您如何在客户端上使用不记名令牌并授权用户?您如何请求刷新令牌?

1 个答案:

答案 0 :(得分:0)

我设法弄清楚了。本质上,我需要使用Identity的JWT库来获得声明。

  1. 需要安装我已经拥有的Nuget System.IdentityModel.Tokens.Jwt 程序包
  2. 为了从JWT访问令牌中获得要求,我需要在线获取下面的代码:

    使用(var client = new HttpClient())         {             HttpResponseMessage结果= client.PostAsync(getTokenUrl,内容).Result;

            string resultContent = result.Content.ReadAsStringAsync().Result;
            var token = JsonConvert.DeserializeObject<Token>(resultContent);
    
            if (string.IsNullOrEmpty(token.access_token))
            {
                ViewBag.Error = "Incorrect Username or Password, Please try again!";
                return View("Login");
            }
    
            var options = new AuthenticationProperties
            {
                AllowRefresh = true,
                IsPersistent = true,
                ExpiresUtc = DateTime.UtcNow.AddSeconds(int.Parse(token.expires_in))
            }; 
    
            /*var claims = new[]
            {
                new Claim(ClaimTypes.Email, account.Login.Email),
                new Claim("AccessToken", $"Bearer {token.access_token}"),
            };*/
    
            //JwtSecurityToken returns all the properties from the token service
            var jwtToken = new JwtSecurityToken(token.access_token);
            var identity = new ClaimsIdentity(jwtToken.Claims, DefaultAuthenticationTypes.ApplicationCookie,ClaimTypes.Name,ClaimTypes.Role);
            Request.GetOwinContext().Authentication.SignIn(options, identity);
    
            if (identity.HasClaim(ClaimTypes.Role, "Admin"))
            {
                return RedirectToAction("Index", "Admin");
            }
    
            return RedirectToAction("Index", "User");
        }
    
相关问题