ServiceStack,身份验证和传递会话标头,请求

时间:2016-05-22 19:41:09

标签: c# authentication servicestack

我需要针对具有自定义UserName和Password的应用程序验证用户。将凭证与数据库中的凭证进行比较,然后可以授权用户。

我将 AppHost 配置为添加用于身份验证的插件:

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

我用[Authenticate]属性

修饰了我的DTO

然后我创建了一个服务来处理身份验证调用:

    public AuthenticateResponse Any(Authenticate request = null)
    {

        var response = new AuthenticateResponse();

        // code to get user from db
        //...

        // check if credentials are ok
            if (passInDB == request.Password)
            {
                var session = this.GetSession();

                session.IsAuthenticated = true;
                session.UserName = userFromDBEntity.Username;
                response.UserId = userFromDBEntity.ID.ToString();
            }

        return response;
    }

客户端应用中,我创建了对服务的调用,以便为我提供身份验证:

        AuthenticateResponse authResponse = client.Post(new Authenticate
        {
            provider = Axo.WebServiceInterface.AxoAuthProvider.Name, //= credentials
            UserName = username,
            Password = password,
            RememberMe = true
        });

然后,仍然在客户端,我写了类似的东西:

            if (authResponse.UserId != null)
            {
                client.AlwaysSendBasicAuthHeader = true;
                client.SessionId = authResponse.SessionId;
            }

..希望了解客户端,现在我是经过身份验证的用户,但在调试到死后我还有一个未经授权的例外。

我能够访问我创建的Authenticate Service,并检查db的凭据,但之后看起来jsonclient需要的东西超过" SessionId"要知道它已经过身份验证,因为我收到任何其他请求的错误。我认为标题丢失了。

我阅读了很多帖子,并且我还尝试定义我的自定义AuthProvider,然后覆盖TryAuthenticate以查看是否可能有帮助(对于某人来说)但该方法甚至不会被解雇..

1 个答案:

答案 0 :(得分:1)

通过继承CredentialsAuthProvider并覆盖TryAuthenticate()来确定userName / password是否有效,使用ServiceStack's Authentication来实现Custom Auth Provider的示例{1}}使用现有数据库中的信息填充用户OnAuthenticated()

IAuthSession

然后要让ServiceStack使用您的AuthProvider,您需要使用AuthFeature插件注册它,例如:

public class CustomCredentialsAuthProvider : CredentialsAuthProvider
{
    public override bool TryAuthenticate(IServiceBase authService, 
        string userName, string password)
    {
        //Add here your custom auth logic (database calls etc)
        //Return true if credentials are valid, otherwise false
    }

    public override IHttpResult OnAuthenticated(IServiceBase authService, 
        IAuthSession session, IAuthTokens tokens, 
        Dictionary<string, string> authInfo)
    {
        //Fill IAuthSession with data you want to retrieve in the app eg:
        session.FirstName = "some_firstname_from_db";
        //...

        //Call base method to Save Session and fire Auth/Session callbacks:
        return base.OnAuthenticated(authService, session, tokens, authInfo);

        //Alternatively avoid built-in behavior and explicitly save session with
        //authService.SaveSession(session, SessionExpiry);
        //return null;
    }
}

如果所有内容都配置正确,您就可以使用任何服务客户端进行身份验证,例如:

//Register all Authentication methods you want enabled for this web app
Plugins.Add(new AuthFeature(() => new AuthUserSession(),
    new IAuthProvider[] {
        new CustomCredentialsAuthProvider(), 
    }
));

如果成功,这将返回填充的authResponse,var authResponse = client.Post(new Authenticate { provider = "credentials", UserName = username, Password = password, RememberMe = true }); Session cookies也将填充在ss-id/ss-pid实例上,然后您将调用受{{1保护的AuthOnly服务属性。

不要实现验证服务

您永远不想实现自己的client ServiceStack已经实现的。插入ServiceStack身份验证的方法是使用上面显示的自定义提供程序。您可以选择忽略ServiceStack的身份验证,在这种情况下,您应该实施自己的自定义身份验证服务,但不应使用分开的现有[Authenticate] DTO或Any(Authenticate request)属性ServiceStack的身份验证支持,并假设您正在调用已注册的AuthProvider。

请求DTO永远不可为空

虽然不相关,但您也绝不想让您的请求DTO可以为空,例如Authenticate。 ServiceStack将始终使用填充的Request DTO调用您的服务,如果没有通过参数,则为空服务,如果没有Request DTO或[Authenticate]请求DTO,它将永远不会调用您的服务。