Заполните AuthContext в gRPC C # из аутентификации JWT - PullRequest
0 голосов
/ 23 октября 2018

В основном то, что я хочу сделать:

  1. на стороне клиента (получить токен, присоединить его как метаданные и отправить его различным службам) - ГОТОВО
  2. На стороне сервера (получить токен, проверить издателя, дату и аудиторию) - ВЫПОЛНЕНО
  3. На стороне сервера (После проверки токена я хотел бызаполните поля AuthContext, чтобы я мог использовать их в моих GrpcServices) - Нужна помощь здесь

Пока мне удается вернуть ClaimsPrinciple из моего tokenChallenger.Метод GetClaimsPrincipal (token), однако я не уверен, как заполнить AuthContext.

Я читал документацию , и мне в основном нужен перехватчик на стороне сервера.

Вот мой код до сих пор

public class AuthInterceptor: Interceptor
{
    private readonly JwtTokenChallenger _tokenChallenger;
    public AuthInterceptor(JwtTokenChallenger tokenChallenger)
    {
        _tokenChallenger = tokenChallenger;
    }


    public override Task<TResponse> UnaryServerHandler<TRequest, TResponse>(TRequest request, ServerCallContext context,
        UnaryServerMethod<TRequest, TResponse> continuation)
    {


        Task<TResponse> response;

        var isThisProtectedMethodAttribute = IsThisProtectedMethod(continuation.Target.GetType(), context);

        if (isThisProtectedMethodAttribute == null) //only protected methods have attributes.
        {
            response = continuation(request, context);
            return response;
        }
        //jwt token validation;
        //populate auth context with claims principle?
        var token = context.RequestHeaders.FirstOrDefault(h => h.Key == "authorization").Value.Split(" ").Last();
        if (token == null)
        {
            context.Status = new Status(StatusCode.Unauthenticated, "Invalid token");
            return default(Task<TResponse>);
        }

        if (ValidateToken(token))
        {
            PopulateAuthContext(token, context);
            return continuation(request, context);
        }
        context.Status = new Status(StatusCode.Unauthenticated, "Invalid token");
        return default(Task<TResponse>);

        //test


    }

    private ProtectedMethod IsThisProtectedMethod(Type t, ServerCallContext context)
    {
        List<ProtectedMethod> returnAttributes = new List<ProtectedMethod>();

        Attribute[] attrs = Attribute.GetCustomAttributes(t);
        foreach (Attribute attr in attrs)
        {
            if (attr is ProtectedMethod a && (a.ProtectedResourceAcceessMethodName == context.Method.Split("/").Last()))
            {
                return a;
            }
        }

        return null;
    }

    private bool ValidateToken(String tokenToValidate)
    {
        return _tokenChallenger.isValidToken(tokenToValidate); 
    }

    private void PopulateAuthContext(String token, ServerCallContext context)
    {
        //help needed?
    }
}

На стороне клиента я использую Java (Android), на стороне сервера я использую C #

Редактировать: токен имеет 2 вещи, которые я хочу, nameidentifier ироли

Ответы [ 2 ]

0 голосов
/ 25 марта 2019

Существует также третий вариант: заполнить новый производный класс ServerCallContext новым AuthContext, заполненным вашими утверждениями.Вы можете кэшировать преобразование из токена

0 голосов
/ 12 ноября 2018

gRPC C # API не позволяет заполнять AuthContext, AuthContext может быть заполнен только gRPC внутри (если вы используете аутентификацию на основе сертификатов TLS).В основном у вас есть две опции:

  1. вы можете заполнить метаданные запроса запросом с дополнительными записями, которые нужно передать фактическим обработчикам методов (перехватчик на стороне сервера может изменять метаданные),Примечание: если вы решили заполнить метаданные, вам нужно быть очень осторожным, чтобы убедиться, что злонамеренный клиент не может отправить соответствующие записи метаданных вместе со своим запросом и, таким образом, подделать, что он был аутентифицирован.Вы можете сделать это, например, добавив еще один перехватчик, который удаляет все конфиденциальные заголовки из всех входящих запросов.

  2. ваш перехватчик может установить значения, связанные с аутентификацией, в контекст выполнения, совместимый с асинхронным/Ждите.Таким образом, значения будут доступны из асинхронных методов, которые реализуют поведение на стороне сервера.См., Например, https://blog.stephencleary.com/2013/04/implicit-async-context-asynclocal.html для получения дополнительной информации о контекстах C #.

...