Servicestack托管在子域并从主域进行身份验证

时间:2017-08-13 16:49:35

标签: android ios asp.net-mvc servicestack

  

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

     

现在我想在子域上托管servicestack让我们说   service.domain.com

     

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

     

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

     

我可以在未来的Android和iOS应用程序中轻松调用此REST API。

     

我做错了吗?

我尝试使用mythz提供的代码,但现在我收到此错误 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"
                ));

        }
}

我做错了什么?

1 个答案:

答案 0 :(得分:0)

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

存储身份验证用户会话

通过它说2个最简单的解决方案是通过使用在两个MVC上配置的相同location which ServiceStack expectsAuthUserSession序列化到distributed Caching Provider来在ServiceStack中存储经过身份验证的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配置sessionId Session Cookie Id,因为您希望客户端将相同的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令牌,以便跨子域工作,需要配置为使用与上述相同的通配符域。 / p>