在身份验证上发送自定义参数

时间:2014-12-22 10:38:44

标签: servicestack

我是服务台新手。我试图弄清楚如何在身份验证上发送自定义参数。 据我所知,这是验证客户端的步骤,而不是在会话中执行一组调用

var jsonClient = new JsonServiceClient("http://localhost:55679/");
var authResponse = client.Send(new Authenticate
{
    provider = "myProvider",
    UserName = "user",
    Password = "pwd",
    RememberMe = true,
}); 
var jResponse = jsonClient.Get<CountriesResponse>(request);
Console.WriteLine(jResponse.Countries.Count);

到目前为止一切顺利,我将apphost配置为以下内容,一切都按预期工作。

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

如果我不想发送ServiceStack.Authenticate,我想发送我的MyAuthenticate,该怎么办? 请求具有相同的自定义属性,像这样的somenthing?

var authResponse = client.Send(new MyAuthenticate
{
    provider = "myProvider",
    UserName = "user",
    Password = "pwd",
    RememberMe = true,
    AppId = "AppId",
    ProjectId = "ProjectId"
});

我的目标是在我对用户进行身份验证时发送自定义参数,而不仅仅是验证内置请求所允许的参数,而不是将这些额外参数存储在我的CustomUserSession中。

由于

1 个答案:

答案 0 :(得分:3)

在QueryString或HttpHeaders

上发送其他信息

由于您无法更改内置Authenticate请求DTO,因此发送其他元数据的一种方法是在QueryString或HTTP Headers上添加额外信息。

如果您想使用.NET服务客户端执行此操作,则需要使用RequestFilter,例如:

var client = new JsonServiceClient(BaseUrl) {
    RequestFilter = req => { 
        req.QueryString["AppId"] = appId;
        req.QueryString["ProjectId"] = appId;
    }
};

var authResponse = client.Send(new Authenticate { ... });

否则,使用ServiceStack的内置HTTP Utils创建自定义请求通常会更灵活,例如:

var url = "{0}/auth/myProvider".Fmt(BaseUrl)
    .AddQueryParam("AppId", appId)
    .AddQueryParam("ProjectId", projectId);

var authResponse = url.PostJsonToUrl(new Authenticate { ... });

在服务器上,当前请求的QueryString中将提供其他数据,您可以从IServiceBaseIRequest args获取这些数据,例如:

public class CustomCredentialsAuthProvider : CredentialsAuthProvider
{
    ...
    public override IHttpResult OnAuthenticated(IServiceBase authService, 
        IAuthSession session, IAuthTokens tokens, Dictionary<string, string> authInfo)
    {
        ...
        var customSession = (CustomUserSession)session;
        customSession.AppId = authService.Request.QueryString["AppId"];
        customSession.ProjectId = authService.Request.QueryString["ProjectId"];
        return base.OnAuthenticated(authService, session, tokens, authInfo);
    }
}

自定义Meta字典现在可用于验证请求DTO

为了使这个用例更容易,Dictionary<string,string> Meta DTO上添加了一个新的Authenticate属性,这使得从类型服务客户端调用更好一点,因为您不必使用过滤器,例如:

var client = new JsonServiceClient(BaseUrl);

var authResponse = client.Send(new Authenticate {
     ... 
     Meta = new Dictionary<string, string> { {"AppId", appId}, {"ProjectId", pId} },
});

您可以直接从Authenticate DTO访问,例如:

var authRequest = (Authenticate)authService.Request.Dto;
customSession.AppId = authRequest.Meta["AppId"];
customSession.ProjectId = authRequest.Meta["ProjectId"];

新的Meta媒体资源可从 v4.0.35 + 获取,目前为available on MyGet

使用您自己的自定义身份验证服务

能够使用您自己的MyAuthenticate DTO的更具破坏性的替代方法是在您自己的服务中处理身份验证请求,然后委托给AuthService,例如:

public class MyAuthenticate : Authenticate 
{ 
    public string AppId { get; set; }
    public string ProjectId { get; set; }
}

public class MyAuthServices : Service
{
    public object Any(MyAuthenticate request)
    {
        using (var auth = base.ResolveService<AuthenticateService>())
        {
            var response = auth.Post(request);
            var authResponse = response as AuthenticateResponse; 
            if (authResponse != null) {
                var session = base.SessionAs<CustomUserSession>();
                session.AppId = request.AppId;
                session.ProjectId = request.ProjectId;
                this.SaveSession(session);
            }
            return response;
        }
    }
}