我有一个在api.mydomain.com上运行API的ServiceStack项目.同一解决方案中的管理项目托管在admin.mydomain.com.登录/注销已由管理应用程序处理,但我想确保在我的api调用上对用户进行身份验证(有时也检查权限).我正在跨项目使用表单身份验证,因此我的api项目可以使用auth cookie.
这是api项目中的web.config身份验证标记:
<authentication mode="Forms">
<forms protection="All" loginUrl="home/denied" slidingExpiration="true" timeout="60" defaultUrl="home/denied" path="/" domain="mydomain.com" name=".myAuth"></forms>
</authentication>
Run Code Online (Sandbox Code Playgroud)
基于此身份验证和授权帖子,我向服务方法添加了[Authenticate]属性,期望它根据IsAuthenticated的值传递/失败.但是,无论是否存在身份验证cookie,它都会每次重定向到"home/denied".(我通过继承AuthenticateAttribute并检查OriginalRequest来确认这一点...当我使用管理应用程序登录时,cookie集已经存在且req.OriginalRequest.IsAuthenticated为真.)
为什么我的请求被重定向,以及如何正确使用管理应用程序中现有的身份验证凭据?
编辑:这是我提出的解决方案.它只需要一个IPrincipal标识来通过身份验证.
public class AuthenticateAspNetAttribute : RequestFilterAttribute
{
public override void Execute(IHttpRequest req, IHttpResponse res, object requestDto)
{
SessionFeature.AddSessionIdToRequestFilter(req, res, null); //Required to get req.GetSessionId()
using (var cache = req.GetCacheClient())
{
var sessionId = req.GetSessionId();
var session = sessionId != null ? cache.GetSession(sessionId) : null;
var originalRequest = (System.Web.HttpRequest) req.OriginalRequest;
var identity = originalRequest.RequestContext.HttpContext.User.Identity;
if (!identity.IsAuthenticated)
AuthProvider.HandleFailedAuth(new …Run Code Online (Sandbox Code Playgroud) 我正在使用ServiceStack/StructureMap/Moq.该服务调用Session,类型为ServiceStack.CacheAccess.ISession.对于单元测试,我使用Moq创建了一个Mock对象,并将其添加到StructureMap配置中:
protected Mock<ISession> sessionMock = new Mock<ISession>();
ObjectFactory.Configure(
cfg =>
{
cfg.For<ISession>().Use(sessionMock.Object);
Run Code Online (Sandbox Code Playgroud)
但是,当Session对象为null时,我并不感到惊讶 - 我很确定我会退出一步.使用模拟对象填充Session属性还需要做什么?
[编辑]这是一个简单的测试场景
要测试的代码.简单的请求/服务
[Route("getKey/{key}")]
public class MyRequest:IReturn<string>
{
public string Key { get; set; }
}
public class MyService:Service
{
public string Get(MyRequest request)
{
return (string) Session[request.Key];
}
}
Run Code Online (Sandbox Code Playgroud)
基础测试类和MockSession类
// test base class
public abstract class MyTestBase : TestBase
{
protected IRestClient Client { get; set; }
protected override void Configure(Container container)
{
// this code is never reached under any of my scenarios …Run Code Online (Sandbox Code Playgroud)