ServiceStack и.NET Core Middleware
Интересно, можно ли использовать ServiceStack на ядре.NET вместе с промежуточным ПО?
В моем случае я хотел бы реализовать API с помощью ServiceStack и использовать политики авторизации и промежуточное ПО openid connect, такое как IdentityServer4.AccessTokenValidation.
Если нет, есть ли альтернативный способ настроить ServiceStack для работы с сервером openid connect?
2 ответа
Вы можете зарегистрировать промежуточное программное обеспечение.NET Core в том же AppHost, что и ServiceStack в.NET Core Apps, поскольку ServiceStack - это просто еще одно промежуточное программное обеспечение в самом конвейере, но встроенные атрибуты и функции аутентификации ServiceStack не будут знать о каких-либо внешних реализациях аутентификации.
Для более интегрированного решения ознакомьтесь с предложенным сообществом ServiceStack.Authentication.IdentityServer, который включает в себя ServiceStack AuthProvider для IdentityServer.
Я склеил ServiceStack и.NET Core следующим кодом. Я не уверен, что это лучший способ заархивировать цель, но пока он работает.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class AuthorizeAttribute : RequestFilterAsyncAttribute, IAuthorizeData
{
public AuthorizeAttribute(ApplyTo applyTo)
: base(applyTo)
{
Priority = -100;
}
public AuthorizeAttribute()
: this(ApplyTo.All)
{
}
public string Policy { get; set; }
public string Roles { get; set; }
public string AuthenticationSchemes { get; set; }
public override async Task ExecuteAsync(IRequest req, IResponse res, object requestDto)
{
var policyProvider = req.TryResolve<IAuthorizationPolicyProvider>();
var filter = new AuthorizeFilter(policyProvider, new[] {this});
var webRequest = req.OriginalRequest as HttpRequest;
var actionContext = new ActionContext(webRequest.HttpContext, new RouteData(), new ActionDescriptor());
var context = new AuthorizationFilterContext(actionContext, new List<IFilterMetadata>());
await filter.OnAuthorizationAsync(context);
if (context.Result is ChallengeResult)
{
res.StatusCode = 401;
res.EndRequest();
}
else if (context.Result is ForbidResult)
{
res.StatusCode = 403;
res.EndRequest();
}
}
}