ServiceStack Authenticate属性不检查用户是否经过身份验证

时间:2013-11-14 16:38:56

标签: authentication servicestack

我试图创建服务只能在客户端通过身份验证时才能访问,并且我放置了Authenticate属性,但它不起作用,因为我可以在未经过身份验证的情况下访问服务。我将Authenticate属性放在Request DTO之前,服务顶部和Action之前。以下是我想要保护的服务的一些代码

[Authenticate]
public class HelloService : Service
{
    public const string HelloServiceCounterKey = "HelloServiceCounter";

    public object Any(HelloRequest request)
    {
            var userSession = SessionAs<AppHost.CustomUserSession>();
            Session.Set(HelloServiceCounterKey, Session.Get<int>(HelloServiceCounterKey) + 1);
            var roles = string.Join(", ", userSession.Roles.ToArray());
            return new HelloResponse { Result = "Hello, " + request.Name + ", your role(s): " + roles };

    }
}

我在AppHost配置(Funq.Container容器)中有这个

Plugins.Add(new AuthFeature(
           () => new CustomUserSession(),
           new[] { new CustomCredentialsAuthProvider() }
       ));

public class CustomUserSession : AuthUserSession
    {
        public string CompanyName { get; set; }
    }

    public class CustomCredentialsAuthProvider : CredentialsAuthProvider
    {
        public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
        {
            if (!Membership.ValidateUser(userName, password)) return false;

            var session = (CustomUserSession)authService.GetSession(false);
            session.CompanyName = "Company from DB";
            session.UserAuthId = userName;
            session.IsAuthenticated = true;

            // add roles 
            session.Roles = new List<string>();
            if (session.UserAuthId == "admin") session.Roles.Add(RoleNames.Admin);
            session.Roles.Add("User");

            return true;
        }
    }

行中访问服务时
var roles = string.Join(", ", userSession.Roles.ToArray());

obviosly返回NULL,因为尚未验证。

在这种情况下应该做什么验证属性?

1 个答案:

答案 0 :(得分:1)

您需要在app主机配置中配置身份验证提供程序,如下所示:

public override void Configure(Container container)
{ 
    Plugins.Add(new AuthFeature(() => new AuthUserSession(), new IAuthProvider[]
                {
                 your providers here...
                 }));

}

编辑:

假设CustomUserSession继承自IAuthSession,您可以更改

 var session = (CustomUserSession)authService.GetSession(false);

 var session = authService.GetSession<CustomUserSession>();

据我所知,你没有在认证后保存会话

尝试这样的事情:

public override object Authenticate(IServiceBase authService, IAuthSession session, ServiceStack.ServiceInterface.Auth.Auth request)
        {

            string userName = request.UserName;
            string password = request.Password;

            if (!LoginMatchesSession(session, userName))
            {
                authService.RemoveSession();
                session = authService.GetSession();
            }

            if (TryAuthenticate(authService, userName, password))
            {
                authService.SaveSession(session, SessionExpiry);
                if (session.UserAuthName == null)
                    session.UserAuthName = userName;
                OnAuthenticated(authService, session, null, null);

                return new AuthResponse
                {
                    UserName = userName,
                    SessionId = session.Id,
                    ReferrerUrl = RedirectUrl
                };
            }

            throw new HttpError(HttpStatusCode.BadRequest, "400", "wrong credentials");

        }


  public override bool TryAuthenticate(IServiceBase authService, string userName, string password)
        {
            var session = authService.GetSession<CustomUserSession>();
           if (!Membership.ValidateUser(userName, password)) return false;


                session.IsAuthenticated = true;
                session.Id = authService.GetSessionId();
                return true;


            }

修改 由于所有会话都在缓存中管理

,因此您需要配置缓存客户端的其他缺失部分

尝试类似的事情:

container.Register<ICacheClient>(new MemoryCacheClient(){FlushOnDispose = false});

您可以使用主机配置更新代码吗?