CustomUserSession分布式缓存问题

时间:2014-07-30 20:18:02

标签: servicestack

我创建了自己的CustomUserSession,它扩展了AuthUserSession,因此允许我覆盖onAuthenticated并设置一些额外的属性。

我已经注册了我的CustomUserSession,如下所示:

public override void Configure(Funq.Container container)
        {
            Plugins.Add(new AuthFeature(
                () => new CustomUserSession(),
                new IAuthProvider[] { new BasicAuthProvider(),
                                      new CredentialsAuthProvider()
                }));

当我登录使用CustomUserSession的服务时,一切正常,即我可以看到一个条目被添加到分布式缓存表(CacheEntry)。

但是,当我在配置为使用分布式缓存的第二个(微)服务上调用安全方法时,我收到401 HTTP状态代码(未授权)。

如果我使两个服务都使用AuthUserSession,那么分布式缓存工作正常,我可以在已登录第一个服务的第二个服务上调用安全方法。

这似乎是ServiceStack中的缺陷/问题,即分布式缓存不能与CustomUserSession一起使用?

在实现CustomUserSession时,是否有已知的解决方法或其他方法可以使分布式缓存工作?

根据需要添加更多信息,我的CustomUserSession如下:

public class CustomUserSession : AuthUserSession
    {
        public bool ProfileCompleted { get; set; }

        public bool RegistrationVerified { get; set; }

        public IUserAuthManager UserAuthManager { get; set; }

        public IRegistrationManager RegistrationManager { get; set; }

        public CustomUserSession()
        {
            HostContext.Container.AutoWire(this);
        }

        public override void OnAuthenticated(IServiceBase authService, IAuthSession session, IAuthTokens tokens, Dictionary<string, string> authInfo)
        {
            base.OnAuthenticated(authService, session, tokens, authInfo);

            // Check if user profile has been completed
            ProfileCompleted = UserAuthManager.ProfileIsComplete(session);

            // Check if the user has verified their comms details
            RegistrationVerified = UserAuthManager.RegistrationIsVerified(session);
        }

        public override void OnRegistered(IServiceBase registrationService)
        {
            base.OnRegistered(registrationService);

            var regDto = registrationService.Request.Dto as Register;

            if (regDto != null)
            {

                RegistrationManager.ProcessNewRegistration(regDto);
            }
            else
            {
                throw new NullReferenceException("Registration DTO NULL Reference");
            }
        }
    }

服务1的我的AppHost配置方法如下:

public override void Configure(Funq.Container container)
        {
            Plugins.Add(new AuthFeature(
                () => new CustomUserSession(),
                new IAuthProvider[] { new BasicAuthProvider(),
                                      new CredentialsAuthProvider()
                }));

            //Register global CORS Headers
            Plugins.Add(new CorsFeature()); 

            Plugins.Add(new RegistrationFeature());
            Plugins.Add(new ValidationFeature());

            AddGlobalResponseFilter();

            SetupAutoMapper();

            container.RegisterAs<CustomRegistrationValidator, IValidator<Register>>();
            container.RegisterValidators(typeof(AppHost).Assembly);

            container.RegisterAs<OrmLiteCacheClient, ICacheClient>();

            var connStr = RoleEnvironment.GetConfigurationSettingValue("UserAuthConnStr");
            container.Register<IDbConnectionFactory>(c => new OrmLiteConnectionFactory(connStr, SqlServerOrmLiteDialectProvider.Instance));

            container.Register<IUserAuthRepository>(c => new OrmLiteAuthRepository(c.Resolve<IDbConnectionFactory>()));
            var userStore = (OrmLiteAuthRepository)container.Resolve<IUserAuthRepository>();       

            //Create 'CacheEntry' RDBMS table if it doesn't exist already
            container.Resolve<ICacheClient>().InitSchema();

            RegisterProfileComponents(container);
            RegisterExtendedRegComponents(container);

            CreateAuthTables(userStore);

            ConfigureMessageQueue(container);
        }

以下是我的GlobalResponseFilter:

private void AddGlobalResponseFilter()
        {
            GlobalResponseFilters.Add((httpReq, httpResp, requestDto) =>
            {
                if (httpReq.OperationName == "Authenticate")
                {
                    if (!httpResp.IsClosed)
                    {
                        httpResp.AddHeader("Profile-Complete", ((CustomUserSession)httpReq.GetSession()).ProfileCompleted.ToString());

                        httpResp.AddHeader("Reg-Verified", ((CustomUserSession)httpReq.GetSession()).RegistrationVerified.ToString());
                    }
                }
            });
        }

我的第二个(微)服务配置方法包含以下内容:

Plugins.Add(new AuthFeature(
                () => new AuthUserSession(),
                new IAuthProvider[] {new CredentialsAuthProvider()
                }));

            //Register global CORS Headers
            Plugins.Add(new CorsFeature()); 

            container.RegisterAs<OrmLiteCacheClient, ICacheClient>();
            container.Register<IDbConnectionFactory>(c => new OrmLiteConnectionFactory(RoleEnvironment.GetConfigurationSettingValue("UserAuthConnStr"), SqlServerOrmLiteDialectProvider.Instance));
            container.Register<IUserAuthRepository>(c => new OrmLiteAuthRepository(c.Resolve<IDbConnectionFactory>()));
            container.Resolve<ICacheClient>().InitSchema();

请注意,第二个服务使用标准的AuthUserSession,只有第一个服务使用CustomUserSession。

我可以在Chrome Rest控制台&amp; Fiddler认为SessionId正在正确传递给第二个服务,但我仍然得到了401响应。

如果我将第一个服务更改为使用标准的AuthUserSession,则一切正常。

**请参阅下面的REQUEST&amp;返回401时的RESPONSE内容:

REQUEST:

GET http://localhost:8088/exercise/analytics?DateFrom=01%2F01%2F2014 HTTP/1.1
Host: localhost:8088
Connection: keep-alive
Accept: application/json
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
Cookie: ss-id=X83GVWXwyMHIWXEw6X1k; ss-pid=ABjuJFUqyHkMUvI7ssyv; X-UAId=10005

响应:

HTTP/1.1 401 Unauthorized
Transfer-Encoding: chunked
Vary: Accept
Server: Microsoft-HTTPAPI/2.0
X-Powered-By: ServiceStack/4.022 Win32NT/.NET
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type
WWW-Authenticate: credentials realm="/auth/credentials"
Date: Wed, 30 Jul 2014 22:00:44 GMT

0

此致 约翰

0 个答案:

没有答案