ServiceStack 5.0 AuthenticateAttribute.Execute()现在返回一个Task

时间:2018-03-27 19:29:13

标签: c# servicestack

我刚刚从4.0升级到ServiceStack 5.0。

重大改变是现在我的Execute()方法覆盖了AuthenticateAttribute.Execute(),因为'AuthenticateAttribute' does not contain a definition for 'Execute'而无效。

AuthenticateAttribute.Execute()现在返回Task(来自System.Threading.Tasks):

    [AsyncStateMachine(typeof(<ExecuteAsync>d__12))]
    public override Task ExecuteAsync(IRequest req, IResponse res, object requestDto);

并且我不确定如何重写我的Execute()以返回任务...它当前被编写为返回类型为void的方法。

我的代码:

public override void Execute(IRequest req, IResponse res, object requestDto)
    {
        if (HostContext.AppHost.HasValidAuthSecret(req))
        {
            return;
        }

        base.Execute(req, res, requestDto);
        if (res.IsClosed)
        {
            return; // AuthenticateAttribute already closed the request (ie auth failed)
        }

        IronUserSession session = req.GetSession() as IronUserSession;

        if (this.HasAnyRoles(req, session))
        {
            return;
        }

        if (this.DoHtmlRedirectIfConfigured(req, res))
        {
            return;
        }

        res.StatusCode = (int) HttpStatusCode.Forbidden;
        res.StatusDescription = ErrorMessages.InvalidRole.Localize(req);
        res.EndRequest();
    }

使用ServiceStack的身份验证是否有解决方法?或者有没有办法重写我的代码来返回任务?我不确定那个任务会是什么...... their documentation is massive但它在Execute()上的内容几乎没有。

2 个答案:

答案 0 :(得分:2)

你可以修改你的方法以返回await AuthProvider.HandleFailedAuth(authProviders[0], session, req, res);之类的东西,它会返回你想要发送的任务。

您是否查看了原始方法的源代码?

public override async Task ExecuteAsync(IRequest req, IResponse res, object requestDto)
{
    if (AuthenticateService.AuthProviders == null)
        throw new InvalidOperationException(
            "The AuthService must be initialized by calling AuthService.Init to use an authenticate attribute");

    if (HostContext.HasValidAuthSecret(req))
        return;

    var authProviders = AuthenticateService.GetAuthProviders(this.Provider);
    if (authProviders.Length == 0)
    {
        await res.WriteError(req, requestDto, $"No registered Auth Providers found matching {this.Provider ?? "any"} provider");
        res.EndRequest();
        return;
    }

    req.PopulateFromRequestIfHasSessionId(requestDto);

    PreAuthenticate(req, authProviders);

    if (res.IsClosed)
        return;

    var session = req.GetSession();
    if (session == null || !authProviders.Any(x => session.IsAuthorized(x.Provider)))
    {
        if (this.DoHtmlRedirectIfConfigured(req, res, true))
            return;

        await AuthProvider.HandleFailedAuth(authProviders[0], session, req, res);
    }
}

参考。 AuthenticateAttribute.cs - https://github.com/ServiceStack/ServiceStack/blob/d1ba794cea08d12adedf198cd10fe7cfe0a9f60e/src/ServiceStack/AuthenticateAttribute.cs

答案 1 :(得分:2)

您可以使用以下命令重写方法以获得异步impl:

public override async Task ExecuteAsync(IRequest req, IResponse res, object requestDto)
{
    if (HostContext.AppHost.HasValidAuthSecret(req))
    {
        return;
    }

    await base.ExecuteAsync(req, res, requestDto);
    if (res.IsClosed)
    {
        return; // AuthenticateAttribute already closed the request (ie auth failed)
    }

    IronUserSession session = req.GetSession() as IronUserSession;

    if (this.HasAnyRoles(req, session))
    {
        return;
    }

    if (this.DoHtmlRedirectIfConfigured(req, res))
    {
        return;
    }

    res.StatusCode = (int) HttpStatusCode.Forbidden;
    res.StatusDescription = ErrorMessages.InvalidRole.Localize(req);
    res.EndRequest();
}