В основном то, что я хочу сделать:
- на стороне клиента (получить токен, присоединить его как метаданные и отправить его различным службам) - ГОТОВО
- На стороне сервера (получить токен, проверить издателя, дату и аудиторию) - ВЫПОЛНЕНО
- На стороне сервера (После проверки токена я хотел бызаполните поля 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 ироли