替代基于cookie的会话/身份验证

时间:2013-05-22 11:37:20

标签: authentication servicestack session-cookies

servicestack中是否有会话功能插件的替代品?在某些情况下,我无法使用cookie来匹配我的服务实现中的授权会话。是否有可能使用请求的http标头中的令牌解析会话?如果浏览器阻止cookie,首选解决方案是什么?

2 个答案:

答案 0 :(得分:7)

我在没有内置身份验证和会话提供程序的情况下使用ServiceStack。

我使用属性作为请求过滤器来收集cookie,请求标头或字符串参数中的用户信息(id和token)。 您可以在用户登录后提供此信息。您在响应中附加一个新cookie,并在呈现视图时在客户端上注入id和令牌信息,因此您可以使用http标头和查询链接参数。

public class AuthenticationAttribute : Attribute, IHasRequestFilter 
{
    public void RequestFilter(IHttpRequest request, IHttpResponse response, object dto)
    {
        var userAuth = new UserAuth { };
        if(!string.IsNullOrWhiteSpace(request.GetCookieValue("auth"))
        {
            userAuth = (UserAuth)request.GetCookieValue("auth");

        } 
        else if (!string.IsNullOrEmpty(request.Headers.Get("auth-key")) &&
            !string.IsNullOrEmpty(request.Headers.Get("auth-id")))
        {
            userAuth.Id = request.Headers.Get("id");
            userAuth.Token = request.Headers.Get("token");
        }
        authenticationService.Authenticate(userAuth.Id, userAuth.token);
    }
    public IHasRequestFilter Copy()
    {
        return new AuthenticationAttribute();
    }
    public int Priority { get { return -3; } } // negative are executed before global requests 
}

如果用户未获得授权,我会重定向他。

我的项目支持SPA。如果用户使用xmlhttprequests消耗API,则使用标头完成身份验证。我在加载页面时在AngularJS上注入了这些信息,并在所有请求(部分视图,api消费等)上重用它。 ServiceStack功能强大,您可以轻松配置AngularJS应用程序和ServiceStack视图引擎并行工作,验证每个请求,全球化您的应用程序等。

如果您没有cookie并且javascript不调用请求,如果您始终生成将id和token作为查询参数传递的链接,则可以支持不使用cookie的身份验证,并通过隐藏的输入传递它们例如,表格。

答案 1 :(得分:4)

@Guilherme Cardoso:在我目前的解决方案中,我使用的是PreRequestFilters和内置会话功能。

我的工作流程/解决方法如下:

当用户获得授权时,我会使用cookie并将其发送到客户端。现在,如果cookie在请求的http-header(授权)中设置,则客户端可以调用服务。

为实现此目的,我使用PreRequestFilter将伪造的授权标头重定向到请求的cookie。现在我可以使用会话功能了。感觉像黑客,但暂时工作; - )

public class CookieRestoreFromAuthorizationHeaderPlugin : IPlugin
{
    public void Register(IAppHost appHost)
    {
        appHost.PreRequestFilters.Add((req, res) =>
            {
                var cookieValue = req.GetCookieValue("ss-id");

                if(!string.IsNullOrEmpty(cookieValue))
                    return;

                var authorizationHeader = req.Headers.Get("Authorization");

                if (!string.IsNullOrEmpty(authorizationHeader) && authorizationHeader.ToLower().StartsWith("basictoken "))
                {
                    var cookie = Encoding.UTF8.GetString(Convert.FromBase64String(authorizationHeader.Split(' ').Last()));

                    req.Cookies.Add("ss-id",new Cookie("ss-id",cookie));
                    req.Items.Add("ss-id",cookie);
                }
            });
    }
}