OWIN - Как проверить токен на предъявителя для ролей после его возврата Auth Server? - PullRequest
0 голосов
/ 23 октября 2018

Я боролся с безопасностью в наших приложениях MVC в течение двух недель.Я настроил Сервер авторизации для генерации токенов, которые будут использоваться двумя клиентскими приложениями MVC.Однако теперь я генерирую токен, и он возвращает клиенту токен-носитель, однако, когда я проверяю утверждение, он возвращает false.

Этот код генерирует токен с сервера аутентификации:

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» я добавляю роли в соответствии с требованиями для идентификатора заявки.

Однако, когда я получаю это на клиенте,токен на предъявителя и не знаю, как преобразовать это в локальную идентификационную информацию, которую я могу объединить, чтобы получить доступ к ролям.Это код для получения 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", "unique_name": ["admin@fsa.co.za", "Admin Admin"], "http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider":" Идентификация ASP.NET "," AspNet.Identity.SecurityStamp ":" de9090f4-bddb-4baf-a62b-38ed0d6528fe "," role ": [" Admin "," Admin "]," UserId ":" 1 "," sub ":" admin@fsa.co.za "," email ":" admin@fsa.co.za "," Verified ":" False "," iss ":" https://localhost:44318/", "aud": "b77f169bd7bf4787b1aed11599861768", "exp": 1540293963,"nbf": 1540292163}

У меня вопрос: как вы на клиенте работаете с токеном-носителем и авторизуете пользователей?Как запросить токен обновления?

1 Ответ

0 голосов
/ 23 октября 2018

Мне удалось понять это.По сути, мне нужно работать с библиотекой JWT Identity, чтобы получить претензии.

  1. Необходимо установить пакет Nuget System.IdentityModel.Tokens.Jwt , который у меня уже был
  2. Чтобы вернуть претензии обратно из токена доступа JWTМне нужно на линии, которая находится в коде ниже:

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}"),
    };*/

    //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");
}
...