gpt4 book ai didi

c# - ServiceStack 中的直通身份验证

转载 作者:太空狗 更新时间:2023-10-29 21:37:51 25 4
gpt4 key购买 nike

我有两个 ServiceStack 服务器 X 和 Y。服务器 X 具有注册和验证用户的功能。它具有 RegistrationFeature、CredentialsAuthProvider、MemoryCacheClient 和 MongoDbAuthRepository 功能来处理身份验证。最近,我引入了服务器 Y 和与服务器 Y 对话的 GUI 表单,以处理我业务领域的另一部分。服务器 Y 需要向服务器 X 上经过身份验证的端点发出请求。

我如何配置服务器 Y,使其在从 GUI 表单收到登录请求时,将该责任传递给有权访问用户信息的服务器 X?

我尝试在服务器 Y 中实现自定义 CredentialsAuthProvider,如下所示:

public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
{
// authenticate through server X
try
{
var client = new JsonServiceClient("http://localhost:8088");
var createRequest = new Authenticate
{
UserName = userName,
Password = password,
provider = Name,
};

var authResponse = client.Post(createRequest);
return true;
}
catch (WebServiceException ex)
{
// "Unauthorized
return false;
}
}

但稍后当我尝试从服务器 Y 中的服务向服务器 X 中经过身份验证的端点发出请求时,出现未授权错误。

public class MyServices2 : Service
{
public object Any(TwoPhase request)
{
try
{
// make a request to server X on an authenticated endpoint
var client = new JsonServiceClient("http://localhost:8088");

var helloRequest = new Hello
{
Name = "user of server Y"
};

var response = client.Post(helloRequest);

return new TwoPhaseResponse { Result = $"Server X says: {response.Result}" };
}
catch (WebServiceException e)
{
Console.WriteLine(e);
throw;
}
}

...
}

最佳答案

这在很大程度上取决于您选择的身份验证方法。如果您想使用 CredentialsAuthProvider,则必须确保每个服务器都配置为使用相同的 distributed Caching Provider instance (即除 MemoryCacheClient 之外的任何缓存提供程序)。这是因为当您通过身份验证时,Session Cookie Ids指向经过身份验证的用户 session 的内容填充在随每个请求一起发送的服务客户端上。接收 session Cookie ID 的 ServiceStack 实例将使用它来访问已注册缓存提供程序中的经过身份验证的用户 session 。

如果两个 ServiceStack 服务都配置为使用相同的缓存提供程序,您可以将 session Cookie 从传入请求传输到新的服务客户端,如下所示:

传输 session ID

public object Any(ClientRequest request)
{
// make a request to server X on an authenticated endpoint
var session = base.SessionAs<AuthUserSession>();
var client = new JsonServiceClient("http://localhost:8088");
client.SetSessionId(session.Id);

var response = client.Post(new Hello {
Name = "user of server Y"
});

return new TwoPhaseResponse { Result = $"Server X says: {response.Result}" };
}

传输 BasicAuthProvider 凭证

否则,如果您将 HTTP Basic Auth 与 BasicAuthProvider 一起使用,则用户名/密码将随请求一起发送,您可以通过以下方式将其传输到您的内部服务客户端:

var basicAuth = base.Request.GetBasicAuthUserAndPassword();
client.UserName = basicAuth.Value.Key;
client.Password = basicAuth.Value.Value;
client.AlwaysSendBasicAuthHeader = true;

这将复制在传入请求中发送的用户名/密码,并将其与传出请求一起发送。但要使其正常工作,必须将两个 ServiceStack 实例配置为使用相同的 BasicAuthProviderUser Auth Repository因为下游服务器需要能够验证提供的用户名/密码。

传输 API key

同样,您可以使用 API Key AuthProvider做类似的事情,而不是转发用户名/密码,你可以转发一个 API key :

var apikey = base.Request.GetApiKey();
client.BearerToken = apikey.Id;

同样,这需要使用相同的 ApiKeyAuthProvider 和 User Auth Repository 配置,因为下游服务器需要验证提供的 API key 。

使用 JWT AuthProvider 进行无状态认证

否则,如果您不希望每个服务器共享相同的基础架构依赖项(例如缓存提供程序/用户身份验证存储库),我会考虑使用 JWT Auth Provider这非常适合使用 one ServiceStack Instance that issues the the JWT Token 进行身份验证的场景封装用户 session 并允许您向其他 ServiceStack 实例发出经过身份验证的请求 just need to have a JwtAuthProviderReader registered .

要转移 JWT token ,您可以通过以下方式访问它:

var bearerToken = base.Request.GetBearerToken()
?? base.Request.GetCookieValue(Keywords.TokenCookie);

并将其填充到内部服务客户端:

client.BearerToken = bearerToken;

关于c# - ServiceStack 中的直通身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43344432/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com