ServiceStack Ws-Security Auth Provider

时间:2015-04-03 09:30:39

标签: servicestack ws-security

我正在试图弄清楚如何在SS中支持ws-security作为身份验证机制。

我的目标是让所有DTO都在json,xml,saop11,saop12中处理(该部分已在SS documentation之后实现)并支持多个auth提供程序,包括一个基于ws-security的提供程序。 DTO不应受到认证机制的影响。

如果使用saop12发送DTO,soap消息将是元数据端点(soap envelope + soap body)生成的调用样本以及包含WS-Security用户名的ws-security元素的soap头验证。一个dedidcated“soap auth提供者”应检查该消息,使用soap标题 - >安全元素并执行身份验证。

与soap auth提供程序一起,我可能有其他内置的auth机制,可用于json消息和/或其他格式。

基于我不知道的ws-security存在SS身份验证提供程序?

有任何指导方针,建议,实施方法吗?

目前比我的解决方案

// APPHOST

Plugins.Add(new AuthFeature(() => new CustomAuthUserSession(),
    new IAuthProvider[] {
        new CustomCredentialsAuthProvider(), 
        new SoapMessageAuthProvider(),
    }
));

// required by the SoapMessageAuthProvider to inspect the message body serching for ws-security element
PreRequestFilters.Add((httpReq, httpRes) =>
{
    httpReq.UseBufferedStream = false;
});

我将SoapMessageAuthProvider基于内置的BasicAuthProvider。 由于SoapMessageAuthProvider需要在ws-security元素的每个调用serching上检查传入消息,因此我实现了IAuthWithRequest

public void PreAuthenticate(IRequest req, IResponse res)
{
    //Need to run SessionFeature filter since its not executed before this attribute (Priority -100)            
    SessionFeature.AddSessionIdToRequestFilter(req, res, null);

    var userPass = ExtractSoapMessageUserNameCredentials(req);//req.GetBasicAuthUserAndPassword();
    if (userPass != null)
    {
        var authService = req.TryResolve<AuthenticateService>();                
        //var response = authService.Post(new Authenticate
        //{
        //  provider = Name,
        //  UserName = userPass.Value.Key,
        //  Password = userPass.Value.Value
        //});

        authService.Request = req;
        var session = authService.GetSession(false);
        var userName = userPass.Value.Key;

        //Add here your custom auth logic (database calls etc)
        var userAuth = new UserAuth();
        userAuth.Id = 10;
        userAuth.UserName = userName;


        var holdSessionId = session.Id;
        session.PopulateWith(userAuth); //overwrites session.Id
        session.Id = holdSessionId;
        session.IsAuthenticated = true;
        session.UserAuthId = userAuth.Id.ToString(CultureInfo.InvariantCulture);
        session.UserAuthName = userName;
    }
}

//called by CustomAuthUserSession.IsAuthorized
// to be reviewed to keep isolated from other providers
public override bool IsAuthorized(IAuthSession session, IAuthTokens tokens, Authenticate request = null)
{
    if (request != null)
    {
        if (!LoginMatchesSession(session, request.UserName))
        {
            return false;
        }
    }

    return !session.UserAuthId.IsNullOrEmpty();//filled by PreAuthenticate
}

自定义会话调用每个提供程序,包括SoapMessageAuthProvider,同时通过PreAuthenticate方法,使用经过身份验证的用户数据填充会话。

public class CustomAuthUserSession : AuthUserSession
{
    public override bool IsAuthorized(string provider)
    {
        var tokens = ProviderOAuthAccess.FirstOrDefault(x => x.Provider == provider);
        return AuthenticateService.GetAuthProvider(provider).IsAuthorizedSafe(this, tokens);
    }
    ...
}

我需要确保始终为soap消息w / ws-security调用soap提供程序,并且该调用不应由其他提供程序进行身份验证: - 用户通过CustomCredentialsAuthProvider获取身份验证(基于cookie) - 用户在携带auth cookie的Web请求中调用service supply json消息 - 另一个呼叫发送携带相同身份验证cookie的soap消息:由于消息是soap格式并且包含soap头ws-security,因此应仅使用soap提供程序使用soap头ws-security对消息进行身份验证

我理解这是一个奇怪的场景,但我正在努力了解如何实现它。

我的猜测是通过ServiceStack.AuthenticateAttribute第72行

发生的
matchingOAuthConfigs.OfType<IAuthWithRequest>()
    .Each(x => x.PreAuthenticate(req, res));

0 个答案:

没有答案