0

我试图使服务只能在客户端经过身份验证并且我放置了 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());

显然返回 NULL 因为尚未经过身份验证。

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

4

1 回答 1

1

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

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});

你能用你的主机配置更新你的代码吗?

于 2013-11-14T19:47:52.197 回答