slug | Título |
---|---|
autenticación-y-autorización |
Autenticación y Autorización |
Integrado en ServiceStack hay un modelo de autenticación simple y extensible que implementa la autenticación de sesión HTTP estándar donde Las cookies de sesión se utilizan para enviar solicitudes autenticadas que hacen referencia a los usuarios de sesión de usuario personalizados POCO en el archivo Proveedor de almacenamiento en caché registrado.
ServiceStack también incluye una serie de proveedores de autenticación que "autentican por solicitud", en este caso la sesión de usuario autenticada
solo se conecta y dura durante la vida útil de la corriente IRequest
. Los detalles de implementación de cada proveedor de autenticación son los siguientes:
transparente para su Aplicación donde se utilizan los mismos Atributos y API para recuperar, validar, autenticar y autorizar a los Usuarios.
El soporte de autenticación de ServiceStack está encapsulado en el complemento opcional, AuthFeature
lo que proporciona una manera fácil de declarar
registre y configure varios proveedores de autenticación que desee permitir en su aplicación. Es altamente configurable con una serie de
características adicionales, como si se habilita el registro integrado para registrar nuevos usuarios, así como los servicios de asignación / anulación de asignación de roles
que los administradores pueden usar para asignar roles/permisos a los usuarios existentes.
La autenticación de ServiceStack también es altamente personalizable y versátil, ya que puede elegir entre la gran cantidad de proveedores de autenticación
disponibles o heredando de ellos para crear su propio proveedor de autenticación personalizado, heredando AuthUserSession
para usar su propio POCO personalizado
con información adicional que desea mantener para sus Usuarios, almacenando Sesiones de Usuario en cualquiera de los Proveedores de Almacenamiento en Caché disponibles,
agregar lógica personalizada mediante el control de cualquiera de los eventos de autenticación y sesión generados a lo largo del ciclo de vida de autenticación,
para especificar en qué repositorio de autenticación de back-end desea conservar sus usuarios autenticados, lo que admite los RDBMS más populares y
almacenes de datos NoSQL populares, como se ve en la descripción general de alto nivel a continuación:
Es AuthenticateService
el servicio principal que administra la autenticación que delega en el proveedor de autenticación especificado que:
realiza la autenticación, disponible a través de sus siguientes puntos de conexión:
/auth/{provider}
- Autenticarse en un proveedor de autenticación específico/auth
- API para comprobar si una solicitud está autenticada: devuelve 200 con información básica de la sesión si está autenticada o 401 si no./auth/logout
- Elimina la sesión autenticada de la caché registrada y borra las cookies de sesión.
Si desea que ServiceStack administre la autenticación completa de sus aplicaciones y la persistencia de los usuarios, debe utilizar uno de los repositorios de autenticación disponibles y autenticarse en uno de los siguientes proveedores de autenticación:
Proveedor | Nombre de la clase | Ruta | Descripción |
---|---|---|---|
Credenciales | CredentialsAuthProvider |
/autenticación/credenciales | Autenticación estándar mediante nombre de usuario/contraseña |
Autenticación básica | BasicAuthProvider |
Autenticación básica HTTP | Nombre de usuario/contraseña enviado a través de HTTP Basic Auth |
Autenticación de resumen | DigestAuthProvider |
Autenticación de resumen HTTP | Hash de nombre de usuario/contraseña a través de HTTP Digest Auth |
Se pueden crear nuevos usuarios a través del /register
servicio de registro que se habilita con:
Plugins.Add(new RegistrationFeature());
Los siguientes proveedores de OAuth están integrados en ServiceStack y se pueden usar en aplicaciones ASP.NET Core y .NET Framework:
Proveedor | Nombre de la clase | Ruta | Crear enlace a la aplicación OAuth |
---|---|---|---|
Facebook (en inglés) | FacebookAuthProvider |
/autenticación/facebook | developers.facebook.com/apps |
TwitterAuthProvider |
/autenticación/twitter | dev.twitter.com/apps | |
Google (en inglés) | GoogleAuthProvider |
/autenticación/google | console.developers.google.com |
GitHub (en inglés) | GithubAuthProvider |
/auth/github | github.com/settings/applications/new |
Microsoft | MicrosoftGraphAuthProvider |
/auth/microsoftgraph | apps.dev.microsoft.com |
LinkedIn (en inglés) | LinkedInAuthProvider |
/autenticación/linkedin | www.linkedin.com/secure/developer |
Yammer | YammerAuthProvider |
/auth/yammer | www.yammer.com/client_applications |
Yandex | YandexAuthProvider |
/auth/yandex | oauth.yandex.ru/client/new |
VK | VkAuthProvider |
/autenticación/vkcom | vk.com/editapp?act=create |
Odnoklassniki | OdnoklassnikiAuthProvider |
/auth/odnoklassniki | www.odnoklassniki.ru/devaccess |
En el siguiente diagrama se describe con más detalle cómo funciona la autenticación estándar basada en sesión y cómo interactúan los diferentes proveedores:
Donde el proveedor de autenticación es único para cada proveedor de autenticación, pero adopta el mismo proceso de autenticación que resulta
en el mismo resultado final en el que se conserva un autenticado AuthUserSession
en el registrado ICacheClient
contra la ss-pid
cookie permanente
si la Authenticate
solicitud RememberMe=true
de lo contrario contra ss-id
la cookie de sesión temporal, si no.
Después de autenticar una solicitud, sus cookies de sesión se envían en solicitudes posteriores y se validan mediante la función integrada [Authenticate]
y
Otros [Require*]
atributos para restringir el acceso a usuarios válidos:
Una vez autenticado, se puede acceder a la sesión de usuarios en sus Servicios utilizando las API con tipo y mínimas IAuthSession
:
AuthUserSession session = base.SessionAs<AuthUserSession>();
IAuthSession session = base.GetSession();
De si se ha registrado para usar un POCO UserSession personalizado en el AuthFeature
constructor, úselo en lugar de AuthUserSession
.
Las sesiones de usuario con tipo también son accesibles en todos los filtros y controladores que tienen acceso a la actual IRequest
con:
AuthUserSession session = req.SessionAs<AuthUserSession>();
IAuthSession session = req.GetSession();
Consulta los documentos de la sesión para obtener más información sobre la personalización de las sesiones y el control de diferentes eventos de sesión y autenticación.
Estos proveedores de autenticación incluyen autenticación con cada solicitud, por lo que la sesión de usuario autenticada solo se rellena en el HTTP IRequest
y no se guarda en el cliente de caché registrado. A diferencia de los proveedores de autenticación tradicionales anteriores, donde hay una solicitud de "Autenticación" separada para establecer la autenticación,
Los proveedores de autenticación que implementan IAuthWithRequest
en su lugar envían su autenticación "por solicitud" donde solo se rellena en el : IRequest
Si bien el proceso de autenticación es diferente, continuaría usando las mismas API y atributos para acceder y validar la sesión de usuarios.
Los siguientes proveedores de autenticación IAuthWithRequest
implementan y autentican por solicitud:
Proveedor | Nombre de la clase | Método de autenticación | Descripción |
---|---|---|---|
JWT | JwtAuthProvider |
Ficha al portador | Proveedor de autenticación sin estado mediante tokens web JSON |
Claves de API | ApiKeyAuthProvider |
Ficha al portador | Permitir el acceso de terceros para autenticarse sin contraseña |
Autenticación básica | BasicAuthProvider |
Autenticación básica | Autenticación mediante autenticación básica HTTP |
Autenticación de resumen | DigestAuthProvider |
Autenticación de resumen | Autenticación mediante HTTP Digest Auth |
Algunos otros proveedores de autenticación especiales que se autentican por solicitud incluyen:
- Autenticación de Windows en
AspNetWindowsAuthProvider
: autenticación mediante autenticación de Windows integrada en ASP.NET. - Claims Auth en
NetCoreIdentityAuthProvider
: pase a través del proveedor de autenticación que delega en ASP.NET Core Identity Auth o Identity Server.
Se NetCoreIdentityAuthProvider
trata de un adaptador de autenticación bidireccional que permite a ServiceStack utilizar la misma autenticación que el
el resto de la aplicación ASP.NET Core y MVC donde habilita los siguientes escenarios populares:
- Uso de ServiceStack Auth en MVC: use ServiceStack Auth para activar ASP.NET Identity Auth, preconfigurado en la plantilla de proyecto mvcauth.
- Uso de la autenticación IdentityServer4 en ServiceStack: utilice IdentityServer4 para autenticar ASP.NET servicios principales y ServiceStack, preconfigurado en la plantilla de proyecto MVCIDENTITYSERVER.
- Azure Active Directory : permitir que la aplicación personalizada inicie sesión con Azure Active Directory
- Azure Active Directory a través de Azure Graph for ServiceStack
- ServiceStack.Authentication.IdentityServer : integración con ASP.NET IdentityServer y proporciona autenticación de inicio de sesión único OpenIDConnect / OAuth 2.0
Una configuración mínima necesaria para poner en marcha la autenticación básica es la siguiente ( AppHost.Config()
derivada de la prueba unitaria AuthTests):
public override void Configure(Container container)
{
Plugins.Add(new AuthFeature(() => new AuthUserSession(),
new IAuthProvider[] {
new BasicAuthProvider(), //Sign-in with HTTP Basic Auth
new CredentialsAuthProvider(), //HTML Form post of UserName/Password credentials
}));
container.Register<ICacheClient>(new MemoryCacheClient());
var userRepo = new InMemoryAuthRepository();
container.Register<IAuthRepository>(userRepo);
//The IAuthRepository is used to store the user credentials etc.
//Implement this interface to adjust it to your app's data storage
}
AuthWebTests es un proyecto sencillo que muestra todos los proveedores de autenticación configurados y funcionando en la misma aplicación. Consulte AppHost para obtener un ejemplo del código y Web.config para obtener un ejemplo de la configuración necesaria para habilitar cada proveedor de autenticación.
Una vez que tenga el ConsumerKey
y ConsumerSecret
necesita configurarlo con su host ServiceStack, a través de Web.config, por ejemplo:
<add key="oauth.RedirectUrl" value="https://yourhostname.com"/>
<add key="oauth.CallbackUrl" value="https://yourhostname.com/auth/{0}"/>
<add key="oauth.twitter.ConsumerKey" value="3H1FHjGbA1N0n0aT5yApA"/>
<add key="oauth.twitter.ConsumerSecret" value="MLrZ0ujK6DwyjlRk2YLp6HwSdoBjtuqwXeHDQLv0Q"/>
Para .NET Core o ASP.NET Core Apps , puede agregar las mismas claves a su appsettings.json
, por ejemplo:
{
"oauth.RedirectUrl": "https://yourhostname.com",
"oauth.CallbackUrl": "https://yourhostname.com/auth/{0}",
"oauth.twitter.ConsumerKey": "3H1FHjGbA1N0n0aT5yApA",
"oauth.twitter.ConsumerSecret": "MLrZ0ujK6DwyjlRk2YLp6HwSdoBjtuqwXeHDQLv0Q",
}
Cada opción de OAuth Config retrocede a la configuración sin el nombre del proveedor. Si es necesario, proporcione una configuración específica de OAuth incluyendo el nombre del proveedor de autenticación en la configuración, por ejemplo:
<add key="oauth.twitter.RedirectUrl" value="https://yourhostname.com"/>
<add key="oauth.twitter.CallbackUrl" value="https://yourhostname.com/auth/twitter"/>
La configuración también se puede especificar en el código al registrar el proveedor de autenticación en el AuthFeature
complemento en su AppHost, por ejemplo:
Plugins.Add(new AuthFeature(() => new AuthUserSession(), new IAuthProvider[] {
new TwitterAuthProvider(appSettings) {
RedirectUrl = "http://yourhostname.com/",
CallbackUrl = "http://yourhostname.com/auth/twitter",
ConsumerKey = "3H1FHjGbA1N0n0aT5yApA",
ConsumerSecret = "MLrZ0ujK6DwyjlRk2YLp6HwSdoBjtuqwXeHDQLv0Q",
},
}));
:::información La URL de devolución de llamada de cada aplicación debe coincidir con la CallbackUrl de la aplicación, que suele ser: http://yourhostname.com/auth/{Provider}, por ejemplo, http://yourhostname.com/auth/twitter para Twitter. :::
Las redirecciones externas utilizadas en los ?continue
parámetros de /auth
las solicitudes están deshabilitadas de forma predeterminada, se pueden volver a habilitar con:
new AuthFeature(...) {
ValidateRedirectLinks = AuthFeature.AllowAllRedirects
}
ServiceStack admite la gestión de usuarios en varios almacenes de datos a través de su repositorio de autenticación, abstracción y proveedores integrados.
Una vez autenticado, el ** modelo AuthUserSession** se rellena y almacena en la caché mediante uno de los proveedores de almacenamiento en caché compatibles con ServiceStack. Las sesiones de ServiceStack simplemente usan el método ICacheClient API para que cualquier nuevo proveedor agregado se pueda usar tanto para la sesión como para el almacenamiento en caché, que actualmente incluye:
- Memoria:
MemoryCacheClient
en ServiceStack - Redis:
RedisClient
,PooledRedisClientManager
oBasicRedisClientManager
en ServiceStack.Redis - OrmLite:
OrmLiteCacheClient
en ServiceStack.Server - AWS DynamoDB:
DynamoDbCacheClient
en ServiceStack.Aws - Memcached:
MemcachedClientCache
en ServiceStack.Caching.Memcached - Azure:
AzureTableCacheClient
en ServiceStack.Azure
La función de autenticación también le permite especificar su propio tipo personalizado IUserAuthSession
donde puede capturar metadatos adicionales con la sesión de sus usuarios que también se conservarán e hidratarán desde la caché, por ejemplo:
Plugins.Add(new AuthFeature(() => new CustomUserSession(),
...
));
:::información
Si está utilizando sesiones personalizadas y tiene JsConfig.ExcludeTypeInfo=true
, debe habilitarlo explícitamente con JsConfig<TCustomSession>.IncludeTypeInfo=true
.
:::
Después de la autenticación, el cliente recibirá una cookie con un ID de sesión, que se utiliza para obtener la sesión correcta internamente ICacheClient
por ServiceStack. Por lo tanto, puede acceder a la sesión actual en un servicio:
public class SecuredService : Service
{
public object Get(Secured request)
{
var session = this.SessionAs<AuthUserSession>();
return new SecuredResponse() { Test = "You're" + session.FirstName };
}
}
Los proveedores de autenticación, almacenamiento en caché y sesión de ServiceStack son API comprobables completamente nuevas, limpias y sin dependencias que no dependen de ASP y carecen de él. Los modelos existentes de membresía, almacenamiento en caché o proveedor de sesiones de NET.
Las solicitudes de superusuario mediante Config.AdminAuthSecret devuelven una UserSession de administrador autenticada
cuyos valores por defecto se pueden modificar en AuthFeature.AuthSecretSession
:
DisplayName
:AdminUserName
: authsecretAuthProvider
: authsecretRoles
:AdminUserAuthId
: 0
AuthFeature
Agrega una página /login.html de reserva si el HtmlRedirect
permanece sin cambios y no /login.html
existe, de lo contrario.
si se usa una /login
página personalizada en Razor o Script Pages, se seguirán usando en su lugar.
La página predeterminada /login.html
proporciona una página de inicio de sesión automático que admite la autenticación a través de credenciales, así como la generación de una dinámica
La lista de proveedores de OAuth, por ejemplo, la página NorthwindCrud /login
con OAuth de Facebook se ve así:
Si usa una aplicación SPA con enrutamiento del lado del cliente para implementar /login
, la página de inicio de sesión predeterminada se puede deshabilitar con:
new AuthFeature {
IncludeDefaultLogin = false
}
La página de inicio de sesión admite los mismos continue
parámetros o ReturnUrl
redireccionamientos que la API de cierre de sesión.
Consulte los documentos de validación mundial anotados para obtener un recorrido detallado y mostrar la implementación de cómo los enfoques **de representación HTML de servidor ** más populares y las tecnologías de representación de la interfaz de usuario del cliente utilizan la misma Autenticación, Registro y Servicios protegidos.
La mayoría de las plantillas de proyecto de ServiceStack están configuradas con autenticación lista para usar o se pueden agregar fácilmente a una web vacía Plantilla de proyecto:
:::Sh x nueva web ProjectName :::
Al mezclar las características de autenticación deseadas, por ejemplo, para configurar su aplicación para habilitar la autenticación y el mantenimiento en SQL Server, ejecute:
:::Sh x mix auth auth-db sqlserver :::
Echa un vistazo a la demo de YouTube de Bookings CRUD para obtener una vista previa rápida de esto en acción.
Para ilustrar la integración de la autenticación con ServiceStack, consulte la autenticación habilitada Demostraciones en vivo a continuación:
- Inicio de sesión de Apple
- Autenticación de Apple
- Reservas CRUD
- Credenciales, Facebook, Google, Microsoft Auth
- Nuevos TechStacks
- GitHub, Twitter y JWT Auth
- SimpleAuth.Mvc
- Twitter, Facebook, GitHub, VK, Yandex y Credentials Auth
- Charlar
- Twitter, Facebook y GitHub Auth
- Android Java Chat
- Facebook, Twitter y Google Auth
- Android Xamarin Chat
- Autenticación de Twitter
- Aplicación HttpBenchmarks
- Guía de autenticación paso a paso
- Twitter, Facebook, Google, LinkedIn y Autenticación de Credenciales
- TechStacks angulares
- Twitter, GitHub y JWT Auth
- Gistlyn
- GitHub y JWT Auth
- Autenticación de AWS
- Twitter, Facebook, GitHub, Google, Yahoo, LinkedIn y autenticación de credenciales
- Ejemplo de MVC y WebForms
- Twitter, Facebook, GitHub, Google, Yahoo, LinkedIn, VK, Credenciales y autenticación de Windows
- Charlar
- Twitter, Facebook y GitHub Auth
- React Chat
- Twitter, Facebook y GitHub Auth
- SocialBootstrap Api
- Twitter, Facebook, Yahoo y Credentials Auth
Un buen punto de partida para crear su propio proveedor de autenticación que se basa en la validación de nombre de usuario y contraseña es crear una subclase CredentialsAuthProvider
e invalidar el bool TryAuthenticate(service, username, password)
método en el que puede proporcionar su implementación personalizada. Si, en cambio, desea autenticarse a través de la autenticación básica HTTP
en BasicAuthProvider
su lugar, haría una subclase.
Tanto el valor predeterminado de BasicAuthProvider como el CredentialsAuthProvider (que extiende) se pueden ampliar y su comportamiento se puede sobrescribir. A continuación se muestra un ejemplo:
using ServiceStack;
using ServiceStack.Auth;
// From v5.10+
public class CustomCredentialsAuthProvider : CredentialsAuthProvider
{
public override async Task<bool> TryAuthenticateAsync(IServiceBase authService,
string userName, string password, CancellationToken token=default)
{
//Add here your custom auth logic (database calls etc)
//Return true if credentials are valid, otherwise false
}
public override async Task<IHttpResult> OnAuthenticatedAsync(IServiceBase authService,
IAuthSession session, IAuthTokens tokens, Dictionary<string, string> authInfo,
CancellationToken token=default)
{
//Fill IAuthSession with data you want to retrieve in the app eg:
session.FirstName = "some_firstname_from_db";
//...
//Call base method to Save Session and fire Auth/Session callbacks:
return await base.OnAuthenticatedAsync(authService, session, tokens, authInfo, token);
//Alternatively avoid built-in behavior and explicitly save session with
//session.IsAuthenticated = true;
//await authService.SaveSessionAsync(session, SessionExpiry, token);
//authService.Request.Items[Keywords.DidAuthenticate] = true;
//return null;
}
}
using ServiceStack;
using ServiceStack.Auth;
public class CustomCredentialsAuthProvider : CredentialsAuthProviderSync
{
public override bool TryAuthenticate(IServiceBase authService,
string userName, string password)
{
//Add here your custom auth logic (database calls etc)
//Return true if credentials are valid, otherwise false
}
public override IHttpResult OnAuthenticated(IServiceBase authService,
IAuthSession session, IAuthTokens tokens,
Dictionary<string, string> authInfo)
{
//Fill IAuthSession with data you want to retrieve in the app eg:
session.FirstName = "some_firstname_from_db";
//...
//Call base method to Save Session and fire Auth/Session callbacks:
return base.OnAuthenticated(authService, session, tokens, authInfo);
//Alternatively avoid built-in behavior and explicitly save session with
//session.IsAuthenticated = true;
//authService.SaveSession(session, SessionExpiry);
//authService.Request.Items[Keywords.DidAuthenticate] = true;
//return null;
}
}
A continuación, debe registrar su proveedor de autenticación de credenciales personalizadas:
//Register all Authentication methods you want to enable for this web app.
Plugins.Add(new AuthFeature(() => new AuthUserSession(),
new IAuthProvider[] {
new CustomCredentialsAuthProvider(), //HTML Form post of User/Pass
}
));
De forma predeterminada, el complemento AuthFeature registra automáticamente las siguientes rutas de servicio (reemplazables):
new AuthFeature = {
ServiceRoutes = new Dictionary<Type, string[]> {
{ typeof(AuthenticateService), new[]{ "/auth", "/auth/{provider}" }},
{ typeof(AssignRolesService), new[]{ "/assignroles" }},
{ typeof(UnAssignRolesService), new[]{ "/unassignroles" }},
}
};
Puede realizar un GET o POST para /auth/logout
cerrar la sesión del usuario autenticado o, si usa el cliente de C#, puede cerrar la sesión con:
client.Post(new Authenticate { provider = "logout" });
Al cerrar la sesión, se eliminará la sesión del usuario del servidor y las cookies de sesión del cliente y se redirigirá a la URL en
continue
o el parámetro ReturnUrl
QueryStringAuthFeature.HtmlRedirectReturnParam
o **FormData Request ** configurado ** ** .
Si no se especifica ninguna redirección, recurrirá a la redirección a session.ReferrerUrl
, Referer
encabezado HTTP o configurado AuthProvider.CallbackUrl
.
En el cliente, puede usar los clientes de servicio de C#/.NET para consumir fácilmente los servicios autenticados.
Para autenticarse usando su CustomCredentialsAuthProvider
mediante POST una Authenticate
solicitud, por ejemplo:
var client = new JsonServiceClient(BaseUrl);
var authResponse = client.Post(new Authenticate {
provider = CredentialsAuthProvider.Name, //= credentials
UserName = "[email protected]",
Password = "p@55w0rd",
RememberMe = true,
});
Si la autenticación se ha realizado correctamente, la instancia del cliente de servicio client
se rellenará con cookies de sesión autenticadas, lo que permitirá llamar a servicios autenticados, por ejemplo:
var response = client.Get(new GetActiveUserId());
Si también se ha registradoBasicAuthProvider
, permitirá que sus servicios acepten la autenticación básica HTTP, que está integrada en los clientes de servicio con los que puede rellenar en el cliente de servicio:
client.UserName = "[email protected]";
client.Password = "p@55w0rd";
Lo que también le permitirá acceder a Servicios protegidos, por ejemplo:
var response = client.Get(new GetActiveUserId());
Aunque detrás de escena termina haciendo 2 solicitudes, la 1ª solicitud envía una solicitud normal que será rechazada con un 401 Unauthorized
y si el servidor indica que tiene el BasicAuthProvider
habilitado volverá a enviar la solicitud con las credenciales de autenticación básica HTTP.
En su lugar, puede guardar la latencia de la solicitud de desafío de autenticación adicional especificando que el cliente siempre debe enviar la autenticación básica con cada solicitud:
client.AlwaysSendBasicAuthHeader = true;
Para autenticarse con su CustomCredentialsAuthProvider
(que hereda de CredentialsAuthProvider) debe PUBLICAR:
POST localhost:60339/auth/credentials?format=json
{
"UserName": "admin",
"Password": "test",
"RememberMe": true
}
Cuando el cliente intenta autenticarse con la solicitud anterior y la autenticación se ha realizado correctamente, el cliente recuperará algunas cookies con un identificador de sesión que identifican al cliente en cada llamada al servicio web.
Para mejorar la integración de OAuth Sign In desde aplicaciones móviles o de escritorio nativas, también puede autenticarse a través de AccessTokens, lo que puede simplificar drásticamente el desarrollo y la experiencia del usuario al poder aprovechar los SDK nativos de Facebook, Twitter y Google Client para iniciar sesión localmente y luego reutilizar su **AccessToken local ** para autenticarse con servidores ServiceStack back-end.
Un ejemplo de uso de esta función es en los inicios de sesión integrados de Facebook, Twitter y Google en Java Chat de Android, que también puede iniciar sesión automáticamente los usuarios con AccessTokens guardados.
Esta capacidad está disponible en los proveedores de OAuth más populares a continuación:
FacebookAuthProvider
- Iniciar sesión con FacebookTwitterAuthProvider
- Iniciar sesión con TwitterGithubAuthProvider
- Iniciar sesión con GithubGoogleOAuth2Provider
- Iniciar sesión con Google
También se puede habilitar en otros proveedores de OAuth2 mediante la implementación VerifyAccessToken
manual
validar si el AccessToken proporcionado es válido con la aplicación OAuth registrada. La API para validar el acceso
Los tokens no forman parte de la especificación de OAuth2 y son diferentes (y a menudo faltan) para otros proveedores de OAuth2.
Por ejemplo, utiliza GoogleOAuth2Provider
una VerifyAccessToken
implementación similar a:
new GoogleOAuth2Provider {
VerifyAccessToken = accessToken => {
var url = $"https://www.googleapis.com/oauth2/v1/tokeninfo?access_token={accessToken}";
var json = url.GetJsonFromUrl();
var obj = JsonObject.Parse(json);
return obj["issued_to"] == ConsumerKey;
}
}
Los clientes pueden utilizar esta característica con las nuevas AccessToken
propiedades y AccessTokenSecret
en las propiedades existentes
Authenticate
Solicitud de DTO, enviada con el proveedor para el que es el AccessToken, por ejemplo:
var response = client.Post(new Authenticate {
provider = "facebook",
AccessToken = facebookAccessToken,
RememberMe = true,
});
:::información
La mayoría de los proveedores de OAuth solo requieren el envío de un AccessToken
con Twitter como la excepción, que también requiere el envío de un AccessTokenSecret
:::
ServiceStack utiliza el proveedor de caché que se registró en el contenedor de IoC:
//Register to use an In Memory Cache Provider (default)
container.Register<ICacheClient>(new MemoryCacheClient());
//Configure an alt. distributed persisted cache, E.g Redis:
//container.Register<IRedisClientsManager>(c =>
// new RedisManagerPool("localhost:6379"));
::: info Consejo Si tiene varios servidores que ejecutan el mismo servicio ServiceStack, puede usar Redis para compartir las sesiones entre estos servidores :::
Por favor, mire SocialBootstrapApi para obtener un ejemplo completo.
:::información Por supuesto, también puede implementar su propio mecanismo de autenticación personalizado. No está obligado a usar el mecanismo de autenticación ServiceStack integrado :::
La forma recomendada de proteger las API es usar los atributos de validación declarativa que, a medida que están desacoplados de cualquier implementación, se pueden anotar de forma segura en las DTO de solicitud sin agregar ninguna dependencia de implementación. Además, al anotar los atributos de autorización y validación en los DTO de solicitud, captura esta información en las DTO reutilizables de las API, filtrando esta información a los clientes donde pueden proporcionar experiencias de usuario enriquecidas.
Los atributos de autorización con tipo disponibles incluyen:
Atributo | Descripción |
---|---|
[ValidateIsAuthenticated] |
Proteger el acceso a esta API solo a los usuarios autenticados |
[ValidateIsAdmin] |
Proteger el acceso a esta API solo a los usuarios administradores |
[ValidateHasPermission] |
Proteja el acceso a esta API solo a los usuarios asignados con TODOS los permisos |
[ValidateHasRole] |
Proteja el acceso a esta API solo a los usuarios asignados con TODOS los roles |
Dónde se pueden anotar en Solicitar DTO para proteger las API:
[ValidateIsAuthenticated] // or [ValidateRequest("IsAuthenticated")]
[ValidateIsAdmin] // or [ValidateRequest("IsAdmin")]
[ValidateHasRole(role)] // or [ValidateRequest($"HasRole(`{role}`)")]
[ValidateHasPermission(permission)] // or [ValidateRequest($"HasPermission(`{permission}`)")
public class Secured {}
El [Authenticate]
atributo de filtro de solicitud le dice a ServiceStack qué servicios necesitan autenticación agregándolo a sus implementaciones de servicio, por ejemplo:
[Authenticate]
public class SecuredService : Service
{
public object Get(Secured request)
{
IAuthSession session = this.GetSession();
return new SecuredResponse() { Test = "You're" + session.FirstName };
}
public object Put(Secured request)
{
return new SecuredResponse() { Test = "Valid!" };
}
public object Post(Secured request)
{
return new SecuredResponse() { Test = "Valid!" };
}
public object Delete(Secured request)
{
return new SecuredResponse() { Test = "Valid!" };
}
}
Si lo desea, esa autenticación solo es necesaria para las solicitudes GET y PUT, por ejemplo, debe proporcionar algunos parámetros adicionales al Authenticate
atributo.
[Authenticate(ApplyTo.Get | ApplyTo.Put)]
ServiceStack también incluye un rol integrado y atributos de autorización basados en permisos donde puede aplicar los atributos de filtro de [Required*]
solicitud en sus clases de servicio para aplicarlos a todos los servicios o limitarlos a un solo servicio:
[Authenticate]
//All HTTP (GET, POST...) methods need "CanAccess"
[RequiredRole("Admin")]
[RequiredPermission("CanAccess")]
public class MyServices : Service
{
public object Get(Secured request) {}
[RequiredPermission("CanAdd")]
public object Put(Secured request) {}
[RequiredPermission("CanAdd")]
public object Post(Secured request) {}
[RequiredPermission("AdminRights", "CanDelete")]
public object Delete(Secured request) {}
}
Ahora el cliente necesita los permisos:
- CanAccess para realizar una solicitud GET
- CanAccess, CanAdd para realizar una solicitud PUT/POST
- CanAccess, AdminRights y CanDelete para realizar una solicitud DELETE
Si, en cambio, desea permitir el acceso a los usuarios en CUALQUIER rol o uso de permisos:
[RequiresAnyRole("Admin","Member")]
[RequiresAnyRole(ApplyTo.Put | ApplyTo.Post, "Admin","Owner","Member")]
[RequiresAnyPermission(ApplyTo.Delete, "AdminRights", "CanDelete")]
public class MyServices : Service
{
public object Get(Secured request) {}
public object Put(Secured request) {}
public object Post(Secured request) {}
public object Delete(Secured request) {}
}
Estos atributos también se pueden aplicar a las DTO de solicitud, sin embargo, como agregarían una dependencia a ServiceStack.dll, se recomienda
Puede proteger los servicios agregando el [Authenticate]
atributo en la Acción:
class MyService : Service
{
[Authenticate]
public object Get(Protected request) { ... }
}
La solicitud DTO
[Authenticate]
class Protected { ... }
O la implementación del servicio
[Authenticate]
class MyService : Service
{
public object Get(Protected request) { ... }
}
O bien, heredando de una clase base
[Authenticate]
class MyServiceBase : Service { ... }
class MyService : MyServiceBase {
public object Get(Protected request) { ... }
}
De lo contrario, puede usar un filtro de solicitudes global si desea restringir todas las solicitudes de otra manera, por ejemplo, algo como:
GlobalRequestFiltersAsync.Add(async (req, res, requestDto) =>
{
if (ShouldProtectRequest(requestDto))
{
await new AuthenticateAttribute().ExecuteAsync(req, res, requestDto);
}
});
El CustomValidationFilter
on all AuthProviders le permite agregar lógica de verificación posterior después de que un usuario haya iniciado sesión con un proveedor de OAuth y se recuperen sus metadatos de OAuth. El filtro le permite devolver un IHttpResult
para controlar qué respuesta de error se devuelve, por ejemplo:
new FacebookAuthProvider(appSettings) {
CustomValidationFilter = authCtx => CustomIsValid(authCtx)
? authCtx.Service.Redirect(authCtx.Session.ReferrerUrl
.AddHashParam("f","CustomErrorCode"))
: null,
}
O podría usarse para redirigir una red o usuarios a una página "No disponible en su área" con:
Plugins.Add(new AuthFeature(...,
new IAuthProvider[] {
new CredentialsAuthProvider {
CustomValidationFilter = authCtx =>
authCtx.Request.UserHostAddress.StartsWith("175.45.17")
? HttpResult.Redirect("http://host.com/are-not-available")
: null
}
}));
La validación de nombre de usuario para todos los repositorios de autenticación se puede configurar en:
Plugins.Add(new AuthFeature(...){
ValidUserNameRegEx = new Regex(@"^(?=.{3,20}$)([A-Za-z0-9][._-]?)*$", RegexOptions.Compiled),
})
En lugar de RegEx, puede optar por validar mediante un predicado personalizado. En el ejemplo siguiente se garantiza que los nombres de usuario no incluyan caracteres específicos:
Plugins.Add(new AuthFeature(...){
IsValidUsernameFn = userName => userName.IndexOfAny(new[] { '@', '.', ' ' }) == -1
})
Utilícelo AccountLockedValidator
para anular la lógica para determinar cuándo una cuenta está bloqueada, por ejemplo, de forma predeterminada, una cuenta está bloqueada cuando tiene un LockedDate
pero
Se puede cambiar para permitir el bloqueo de cuentas en una fecha futura con:
new CredentialsAuthProvider {
AccountLockedValidator = (authRepo, userAuth, tokens) =>
userAuth.LockedDate != null && userAuth.LockedDate <= DateTime.UtcNow;
}
Como alternativa, si usa un proveedor de autenticación personalizado, puede invalidar IsAccountLocked()
para invalidar este comportamiento.
La nueva SaveExtendedUserInfo
propiedad (habilitada de forma predeterminada) en todos los proveedores de OAuth le permite controlar si desea guardar los metadatos de OAuth extendidos disponibles (en UserAuthDetails.Items
) al iniciar sesión a través de OAuth.
La MaxLoginAttempts
función le permite bloquear una cuenta de usuario después de varios intentos de inicio de sesión no válidos, por ejemplo:
Plugins.Add(new AuthFeature(...) {
MaxLoginAttempts = 5 // Lock user after 5 Invalid attempts
});
Los plugins pueden registrar AuthProviders llamando antes RegisterAuthProvider()
de que se AuthFeature
registre el plugin, lo que se puede lograr en los plugins haciendo que implementen IPreInitPlugin
:
public class MyPlugin : IPreInitPlugin
{
public void BeforePluginsLoaded(IAppHost appHost)
{
appHost.GetPlugin<AuthFeature>().RegisterAuthProvider(new MyAuthProvider());
}
}
Los proveedores de autenticación pueden personalizar el AuthenticateResponse
valor devuelto implementando IAuthResponseFilter
dónde
se devolverá la llamada con un AuthFilterContext rellenado para las solicitudes DTO de solicitud de autenticación correctas o AuthResultContext
para las solicitudes de OAuth correctas:
public interface IAuthResponseFilter
{
// Intercept successful Authenticate Request DTO requests
void Execute(AuthFilterContext authContext);
// Intercept successful OAuth redirect requests
Task ResultFilterAsync(AuthResultContext authContext, CancellationToken token=default);
}
public class AuthFilterContext
{
public AuthenticateService AuthService // Instance of AuthenticateService
public IAuthProvider AuthProvider // Selected Auth Provider for Request
public IAuthSession Session // Authenticated Users Session
public Authenticate AuthRequest // Auth Request DTO
public AuthenticateResponse AuthResponse // Auth Response DTO
public string ReferrerUrl // Optimal Session Referrer URL to use redirects
public bool AlreadyAuthenticated // If User was already authenticated
public bool DidAuthenticate // If User Authenticated in this request
}
public class AuthResultContext
{
public IHttpResult Result // Response returned for this successful Auth Request
public IServiceBase Service // Instance of Service used in this Request
public IRequest Request // Current HTTP Request Context
public IAuthSession Session // Authenticated Users Session
}
Los filtros se pueden usar para modificar las propiedades de las AuthenticateResponse
solicitudes de redireccionamiento correctas de DTO u OAuth.
Para reemplazar completamente el AuthenticateResponse
valor devuelto, puede especificar un AuthFeature.AuthResponseDecorator
archivo .
La ICustomUserAuth
interfaz se puede implementar en repositorios de autenticación de usuario que permiten reemplazar el
UserAuth
y UserAuthDetails
tablas devolviendo el tipo concreto que se debe usar en su lugar:
public interface ICustomUserAuth
{
IUserAuth CreateUserAuth();
IUserAuthDetails CreateUserAuthDetails();
}
Esto permite usar el mismo RegistrationFeature
y RegisterService
manejar el registro de nuevos usuarios
con los sustituidos IUserAuth
y IUserAuthDetails
Tipos.
LoadUserAuthFilter activado AspNetWindowsAuthProvider
permite recuperar información más detallada sobre los usuarios autenticados de Windows durante la autenticación de autenticación de Windows mediante el archivo . Los servicios de ActiveDirectory de NET, por ejemplo:
//...
new AspNetWindowsAuthProvider(this) {
LoadUserAuthFilter = LoadUserAuthInfo
}
//...
public void LoadUserAuthInfo(AuthUserSession userSession,
IAuthTokens tokens, Dictionary<string, string> authInfo)
{
if (userSession == null) return;
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain))
{
var user = UserPrincipal.FindByIdentity(pc, userSession.UserAuthName);
tokens.DisplayName = user.DisplayName;
tokens.Email = user.EmailAddress;
tokens.FirstName = user.GivenName;
tokens.LastName = user.Surname;
tokens.FullName = (String.IsNullOrWhiteSpace(user.MiddleName))
? $"{user.GivenName} {user.Surname}"
: $"{user.GivenName} {user.MiddleName} {user.Surname}";
tokens.PhoneNumber = user.VoiceTelephoneNumber;
}
}
Utiliza AspNetWindowsAuthProvider
la API pública IPrincipal.IsInRole()
para determinar si un usuario está en un rol de autenticación de Windows en particular, sin embargo, esto puede ser lento cuando se necesita consultar una gran cantidad de roles en LDAP, ya que tendría que realizar una búsqueda de LDAP para cada rol.
El rendimiento de esto ahora se puede mejorar especificando una implementación personalizada PopulateUserRoles
que anule cómo se resuelven los roles de usuario, por ejemplo:
new AspNetWindowsAuthProvider (AppSettings) {
PopulateUserRoles = (request, user, session) => {
using (WindowsIdentity userId = request?.LogonUserIdentity)
{
List roles = new List();
if (userId?.Groups != null)
{
foreach (var group in userId.Groups)
{
// Remove the domain name from the name of the group,
// if it has it, and you don't need it.
var groupName = new SecurityIdentifier(group.Value)
.Translate(typeof(NTAccount)).ToString();
if (groupName.Contains("\"))
groupName = groupName.Split('\')[1];
roles.Add(groupName);
}
}
session.Roles = roles;
}
}
}
Puede habilitar la CredentialsAuthProvider
opción para permitir que ** las solicitudes en proceso se autentiquen sin una contraseña con:**
new CredentialsAuthProvider {
SkipPasswordVerificationForInProcessRequests = true,
}
Cuando está habilitado, permite ** que las solicitudes de servicio en proceso inicien sesión como un usuario especificado sin necesidad de proporcionar su contraseña. **
Por ejemplo, esto podría usarse para crear un servicio de solo administrador restringido ** en la intranet** que le permita iniciar sesión como otro usuario para que pueda depurar su cuenta sin conocer su contraseña con:
[RequiredRole("Admin")]
[Restrict(InternalOnly=true)]
public class ImpersonateUser
{
public string UserName { get; set; }
}
public class MyAdminServices : Service
{
public async Task<object> Any(ImpersonateUser request)
{
using var service = base.ResolveService<AuthenticateService>(); //In Process
return await service.PostAsync(new Authenticate {
provider = AuthenticateService.CredentialsProvider,
UserName = request.UserName,
});
}
}
:::información
Sus servicios pueden usar el nuevo Request.IsInProcessRequest()
para identificar los servicios que se ejecutaron en proceso
:::
El proveedor de autenticación JWT permite un enfoque más flexible para suplantar a los usuarios, ya que lo permiten Creación manual de tokens JWT para construir una sesión de usuario personalizada con metadatos personalizados, Roles y permisos.
IAuthMetadataProvider proporciona una manera de personalizar authInfo en todos los AuthProviders. También permite anular cómo se devuelven los metadatos de autenticación extendidos, como profileUrl.
public interface IAuthMetadataProvider
{
void AddMetadata(IAuthTokens tokens, Dictionary<string,string> authInfo);
string GetProfileUrl(IAuthSession authSession, string defaultUrl = null);
}
:::información
Para invalidar con una implementación personalizada, regístrese IAuthMetadataProvider
en el IOC
:::
AuthFeature también regenera nuevas cookies de sesión cada vez que los usuarios inician sesión, este comportamiento se puede deshabilitar con:
Plugins.Add(new AuthFeature(...) {
GenerateNewSessionCookiesOnAuthentication = false
});
Los proveedores de OAuth pueden usar ClientId
ClientSecret
alias and en lugar de ConsumerKey
y ConsumerSecret
, por ejemplo:
<appSettings>
<add key="oauth.twitter.ClientId" value="..." />
<add key="oauth.twitter.ClientSecret" value="..." />
</appSettings>
Los filtros de solicitud pueden anular el encabezado HTTP de autorización utilizado en los proveedores de autenticación con:
httpReq.Items[Keywords.Authorization] = $"Bearer {token}";
Las solicitudes GET /auth/{provider}
están deshabilitadas de forma predeterminada para desalentar el envío de información confidencial en la dirección URL.
Las excepciones actuales que aún permiten ** solicitudes GET** incluyen:
/auth
- Se utiliza para comprobar si un usuario está autenticado/auth/logout
- Cerrar sesión- Todos los proveedores de OAuth que inician su flujo de OAuth navegando a
/auth/{provider}
Puede permitir **** solicitudes de autenticación GET con:
new AuthFeature {
AllowGetAuthenticateRequests = req => true
}
Aunque se recomienda cambiar el código para usarlo POST
en lugar de GET
solicitudes.
De lo contrario, puede utilizar el IRequest req
parámetro para comprobarlo en una lista blanca de tipos de solicitudes conocidas.
- Autenticación sencilla de servicios web con ServiceStack de @steveellwood
- Uso de IdentityServer 4 con ServiceStack y Angular por @estynedwards
- Adición de la autenticación de Facebook mediante ServiceStack por @markholdt
- Cómo devolver tipos de colección con formato JSV de SQL Server en OrmLite por AdamAnderson
- Cómo migrar usuarios de membresía de ASP.NET a ServiceStack por AdamAnderson
- Autenticación en servicios REST de ServiceStack por @binaryforge
- Creación de un servidor de recursos OAuth2 de ServiceStack mediante DotNetOpenAuth por @dylanbeattie
- Autorización declarativa en servicios REST en SharePoint con F# por @sergey_tihon
- Autenticación de los servicios de ServiceStack con un proveedor de membresía de Umbraco por Gavin Faux
- Uso de OAuth con ArcGIS Online y ServiceStack por @davetimmins
- Proveedor de LinkedIn para la autenticación de ServiceStack por @binu_thayamkery
- Una guía paso a paso para crear un IAuthProvider personalizado de @rngoodness
- Autenticación sencilla de claves API con ServiceStack de @rossipedia
- CORS BasicAuth en ServiceStack con autenticación personalizada por @joeriks
- Autenticación de la API REST de ServiceStack mediante HMAC por @jokecamp
- Autenticación de credenciales de ServiceStack y EasyHttp: Parte 1, Parte 2, Parte 3 por @chrissie1