ASP. NET core 3 Индивидуальная аутентификация с jwt - PullRequest
0 голосов
/ 04 февраля 2020

Я использую токены jwt в своем проекте. Когда клиент входит в систему, он получит токен с идентификатором своего устройства (в мобильном телефоне), который был отправлен на сервер в теле запроса, в качестве полезной нагрузки ...

То, что я хочу сделать, это для дальнейшие запросы, когда клиент отправляет свой идентификатор устройства в теле (как соглашение в моем проекте) и, конечно, токен в запросе заголовка, я хочу проверить, равны ли идентификатор устройства и полезная нагрузка токена.

Я сделал это в сервисе, подобном этому:

public class AuthenticationService
{
    public bool IsAuthenticated(HttpRequest req, string deviceId)
    {


        var token = req.Headers["authorization"];
        var handler = new JwtSecurityTokenHandler();

        JwtSecurityToken tokenS;  

        foreach (var stringValue in token)
        {
            var ss = stringValue.Replace("Bearer ", "");
            if (handler.CanReadToken(ss))
            {
                tokenS = handler.ReadToken(ss) as JwtSecurityToken;
                return tokenS.Claims.Any(c => c.Value == deviceId);

            }
        }

        return false;
    }
}

И я должен внедрить его в каждый контроллер, для которого я хочу авторизовать пользователя ...

if (_authenticationService.IsAuthenticated(Request, deviceId))
        {
            _logger.LogInformation("authorized!");
        }
        else
        {
            _logger.LogCritical("unauthorized");
        }

Я хочу знать, что, если есть более чистый способ сделать это? Что нужно сделать в классе запуска при настройке аутентификации:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters()
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(
                        Configuration.GetSection("AppSettings:Token").Value)),
                    ValidateIssuer = false,
                    ValidateAudience = false,

                };
            });

1 Ответ

1 голос
/ 05 февраля 2020
Расширение

AddJwtBearer будет сопоставлять заявки в токене с клиам пользователя. Идентификатор устройства можно получить по (если тип клиама deviceId):

var deviceID= context.HttpContext.User.Claims.Where(x => x.Type == "deviceId").FirstOrDefault().Value;

Затем вы можете использовать Filter или Middleware. прочитать тело запроса и сравнить идентификатор устройства в теле запроса с идентификатором, указанным в заявке пользователя. Например, если используется фильтр:

public class CustomActionFilter : ActionFilterAttribute
{
    public override async void OnActionExecuting(ActionExecutingContext context)
    {

        if (context.HttpContext.User.Identity.IsAuthenticated) { 

        //read request body 
        var bodyStr = "";
        var req = context.HttpContext.Request;
        req.EnableBuffering();
        req.Body.Position = 0;
        using (var stream = new StreamReader(req.Body))
        {
            bodyStr = await stream.ReadToEndAsync();
        }

        // here you get device ID from bodyStr ,for example : deviceIDFromReq

        var deviceID= context.HttpContext.User.Claims.Where(x => x.Type == "deviceId").FirstOrDefault().Value;

        // then compare 

        if (deviceIDFromReq.Equals(deviceID))
        {
            context.Result = new BadRequestObjectResult(new
            {
                status = "error",
                description = "deviceID not matched"
            });
        }
        }
        base.OnActionExecuting(context);
    }
}

Зарегистрируйтесь как глобальный фильтр:

services.AddControllers(config =>
{
    config.Filters.Add<CustomActionFilter>();

});
...