【问题标题】:Populate AuthContext in gRPC C# from JWT Authentication通过 JWT 身份验证在 gRPC C# 中填充 AuthContext
【发布时间】:2019-03-27 18:14:39
【问题描述】:

基本上我想做的事:

  1. 客户端(获取令牌,附加为元数据令牌并将其发送到不同的服务)--DONE
  2. 服务器端(获取令牌、验证发行者、日期和受众)--DONE
  3. 服务器端(验证令牌后,我想填充 AuthContext 的字段,以便我可以在我的 GrpcServices 中使用它们) -- 这里需要帮助

到目前为止,我设法从我的 tokenChallenge.GetClaimsPrincipal(token) 方法返回了 ClaimsPrinciple,但是我不确定如何填充 AuthContext。

我正在阅读documentation,我基本上需要一个服务器端的拦截器。

这是我目前的代码

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 个我想要的东西,名称标识符和角色

【问题讨论】:

    标签: c# jwt interceptor grpc


    【解决方案1】:

    gRPC C# API 不允许您填充 AuthContext,AuthContext 只能由 gRPC 在内部填充(如果您使用基于 TLS 证书的身份验证)。 你基本上有两个选择:

    1. 您可以使用需要传递给实际方法处理程序的附加条目来填充请求的请求元数据(服务器端拦截器可以修改元数据)。注意:如果您决定填充元数据,您需要非常小心,以确保恶意客户端无法将相应的元数据条目与她的请求一起发送,从而假装她已通过身份验证。你可以这样做,例如通过添加一个拦截器,从所有传入请求中去除所有敏感标头。

    2. 您的拦截器可以将与身份验证相关的值设置为与 async/await 兼容的执行上下文。这样,可以从实现服务器端行为的异步方法访问这些值。参见例如https://blog.stephencleary.com/2013/04/implicit-async-context-asynclocal.html 了解有关 C# 上下文的更多信息。

    【讨论】:

      【解决方案2】:

      还有第三个选项,填充 ServerCallContext 的新派生类,并使用您的声明填充新的 AuthContext。您可以缓存令牌中的转换

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-07-21
        • 2016-06-25
        • 2021-03-25
        • 2023-04-09
        • 2022-09-28
        • 1970-01-01
        • 2019-03-08
        • 2019-06-05
        相关资源
        最近更新 更多