【问题标题】:Servicestack hosting on subdomain and authenticating from main domainServicestack 在子域上托管并从主域进行身份验证
【发布时间】:2017-08-14 23:38:41
【问题描述】:

我正在使用身份 (OWIN) 在 asp.net MVC 中创建一个 Web 应用程序 框架。现在它将托管在一个域中,比如说 domain.com

现在我想在子域上托管服务堆栈让我们说 service.domain.com

现在任何使用用户名和密码登录 domain.com 的用户,如果 它成功了,然后我也想验证 servicestack 以便所有 具有 [Authenticate] 属性的服务将起作用。

在子域上托管 servicestack 的主要目标是使 代码独立于数据库端。

而且我可以在我未来的 Android 和 iOS 应用中轻松调用这个 REST api。

是不是我做错了什么?

我已尝试使用 myz 提供的代码,但现在我收到此错误 AuthKey required to use: HS256

我的 MVC 代码是(运行在:localhost:51055)

    var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);

    switch (result)
    {
           case SignInStatus.Success:
           {
                var jwtProvider = new JwtAuthProvider();

                        var header = JwtAuthProvider.CreateJwtHeader(jwtProvider.HashAlgorithm);
                        var body = JwtAuthProvider.CreateJwtPayload(new AuthUserSession
                        {
                            UserAuthId = user.Id,
                            DisplayName = user.NameSurname,
                            Email = user.Email,
                            IsAuthenticated = true,
                        },
                            issuer: jwtProvider.Issuer,
                            expireIn: jwtProvider.ExpireTokensIn,
                            audience: jwtProvider.Audience,
                            roles: new[] { "TheRole" },
                            permissions: new[] { "ThePermission" });

                        var jwtToken = JwtAuthProvider.CreateJwt(header, body, jwtProvider.GetHashAlgorithm());

                        var client = new JsonServiceClient("http://localhost:52893/");
                        client.SetTokenCookie(jwtToken);

          }
    }

此语句出现错误jwtProvider.GetHashAlgorithm()

我的任何 servicestack 代码都是(运行在:localhost:52893)

public class AppHost : AppHostBase
    {
        public AppHost() : base("MVC 4", typeof(HelloService).Assembly) { }

        public override void Configure(Funq.Container container)
        {
            SetConfig(new HostConfig
            {
                RestrictAllCookiesToDomain = "localhost",
                HandlerFactoryPath = "api",
                DebugMode = true
            });

Plugins.Add(new AuthFeature(() => new AuthUserSession(),
                new IAuthProvider[] {
                    new JwtAuthProviderReader(AppSettings) {
                        AuthKey = AesUtils.CreateKey(),
                        HashAlgorithm = "RS256"
                    },
                }));

            Plugins.Add(new CorsFeature(
                    allowOriginWhitelist: new[] {
                        "http://localhost",
                        "http://localhost:51055"
                    },
                    allowCredentials: true,
                    allowedMethods: "GET, POST, PUT, DELETE, OPTIONS",
                    allowedHeaders: "Content-Type, Allow, Authorization, Wait, Accept, X-Requested-With, Put-Default-Position, Put-Before, If-Match, If-None-Match, Content-Range",
                    exposeHeaders: "Content-Range"
                ));

        }
}

我做错了什么吗?

【问题讨论】:

  • 你能详细解释一下吗
  • 这没问题.. 但是如果有人在 web 中注销然后 api 也会做同样的事情......所以用户会感到恼火..

标签: android ios asp.net-mvc servicestack


【解决方案1】:

您希望通过使用来自 MVC (OWIN) 的身份验证和 ServiceStack 将 2 个不同的框架集成在一起 - 一个独立的框架,没有任何 OWIN 或 MVC 身份验证的耦合或知识。通过尝试将身份验证从一个域转移到不同子域的不同框架中,这进一步混为一谈。通常尝试在完全不同的框架之间集成身份验证是一项艰巨的工作,并且要求它跨子域工作会增加更多的复杂性。

存储验证用户会话

话虽如此,两个最简单的可行解决方案是通过使用在 MVC 和 ServiceStack 应用程序上配置的相同 distributed Caching Provider 将 AuthUserSession 序列化到 location which ServiceStack expects 中,将经过身份验证的 UserSession 存储在 ServiceStack 中。

所以你可以配置ServiceStack to use a Redis CacheClient你可以在MVC中创建和存储一个UserSession:

var session = new AuthUserSession {
    UserAuthId = userId,
    DisplayName = userName,
    Email = userEmail,
    IsAuthenticated = true,
};

然后在MVC中使用configured Redis Manager保存:

var sessionId = SessionExtensions.CreateRandomSessionId();
using (var redis = redisManager.GetClient())
{
    redis.Set($"urn:iauthsession:{sessionId}", session);
}

要让 ServiceStack 使用此 Authenticated UserSession,您需要配置 ss-id Session Cookie Id 和 sessionId,并且由于您希望客户端将相同的 Cookie 发送到子域,您需要配置 Cookie to use a wildcard domain。

使用 JWT

不需要共享任何基础设施依赖项的替代方案(也是我首选的解决方案)是使用无状态 JWT 令牌,它将用户会话封装在 JWT 令牌中。要在 MVC 中执行此操作,您将创建一个 JWT Token from an Authenticated User Session,您可以将其发送到 ServiceStack AppHost configured with the same JwtAuthProvider。

然后,客户端可以通过 sending JWT Tokens in the JWT Cookie 发出经过身份验证的请求,即在 ss-tok cookie 中发送 JWT 令牌,需要将其配置为使用与上述相同的通配符域。

【讨论】:

  • 您可能知道使用 servicestack 的主要目标是我的数据库端代码驻留在 servicestack 中(托管在子域中)。这样我就可以在我的 web、android、ios 和 window 应用程序中轻松调用它。目前我在我的 asp.net mvc 项目中使用了 servicestack.MVC。因此,当用户登录并且如果成功,那么它也会对 servicestack 进行身份验证。当用户注销时,我也会从 servicestack 中注销。
  • @SohebRapati 请仔细阅读JWT documentation,您的JwtAuthProvider 配置不正确,您需要在MVC 和ServiceStack 上使用精确配置,即您不能根据 JWT 文档的第一段使用内存中的 AesUtils.CreateKey()。
  • @SohebRapati 如果您仍然不确定,请查看JwtAuthProviderTests.cs 和StatelessAuthTests.cs 的工作示例。
猜你喜欢
  • 1970-01-01
  • 2019-02-25
  • 1970-01-01
  • 1970-01-01
  • 2014-10-25
  • 2021-12-20
  • 2017-08-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多