我试图创建服务只能在客户端通过身份验证时才能访问,并且我放置了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,因为尚未验证。
在这种情况下应该做什么验证属性?
答案 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});
您可以使用主机配置更新代码吗?