servicestack,restsharp,C#,Authentication,Testing,servicestack,Restsharp" /> servicestack,restsharp,C#,Authentication,Testing,servicestack,Restsharp" />

C# 如何让ServiceStack测试使用RestSharp进行身份验证?

C# 如何让ServiceStack测试使用RestSharp进行身份验证?,c#,authentication,testing,servicestack,restsharp,C#,Authentication,Testing,servicestack,Restsharp,我在ServiceStack应用程序中实现了CustomCredentialAuth的工作实现。我可以用身份验证凭据点击URL,它可以按预期工作 然而,在我的测试中,我的运气不一样 我正在使用RestSharp,如果禁用[Authenticate],我可以通过所有测试 启用[Authenticate]并运行测试会给我 预期:正常 但是:未经授权 这是我的测验。如何让RestSharp为我的测试进行身份验证 使用系统; Net系统; 使用FutureState.AppCore.Tests.Inte

我在ServiceStack应用程序中实现了CustomCredentialAuth的工作实现。我可以用身份验证凭据点击URL,它可以按预期工作

然而,在我的测试中,我的运气不一样

我正在使用RestSharp,如果禁用
[Authenticate]
,我可以通过所有测试

启用
[Authenticate]
并运行测试会给我

预期:正常
但是:未经授权

这是我的测验。如何让RestSharp为我的测试进行身份验证

使用系统;
Net系统;
使用FutureState.AppCore.Tests.Integration.Repositories.fixture;
使用NUnit.Framework;
使用RestSharp;
命名空间FutureState.AppCore.Tests.Functional.Services
{
[测试夹具]
公共类UserServiceInterfaceTests
{
私有RestSchemaValidator_RestSchemaValidator;
私有字符串_testLoginEmail;
私有字符串_testLoginPassword;
[设置]
公共无效设置()
{
_restSchemaValidator=新的restSchemaValidator();
_testLoginEmail=UserFixture.SystemAccount.Email;
_testLoginPassword=“密码”;
}
[测试]
public void应该GetAlistOfUsers和ReturnStatusOK()
{
//设置
var client=新的RestClient(serviceTasAppHostBase.BaseUrl);
client.Authenticator=新的HttpBasicAuthenticator(\u TestLoginMail,\u testLoginPassword);
var request=new RestRequest(“/users/”,Method.GET){RequestFormat=DataFormat.Json};
//执行
var response=client.Execute(请求);
//断言
Assert.That(response.ErrorMessage,Is.Null);
Assert.That(response.StatusCode,Is.EqualTo(HttpStatusCode.OK));
_restSchemaValidator.ValidateResponse(“ExpectedUserResponse.json”,response.Content);
}
[测试]
public void应获取auserandreturnstatusOK()
{
//设置
var expectedUserId=新Guid(UserFixture.FirstUserId);
var client=新的RestClient(serviceTasAppHostBase.BaseUrl);
client.Authenticator=新的HttpBasicAuthenticator(\u TestLoginMail,\u testLoginPassword);
var request=new RestRequest(“/users/”+expectedUserId,Method.GET){RequestFormat=DataFormat.Json};
//执行
var response=client.Execute(请求);
//断言
Assert.That(response.ErrorMessage,Is.Null);
Assert.That(response.StatusCode,Is.EqualTo(HttpStatusCode.OK));
_restSchemaValidator.ValidateResponse(“ExpectedUserResponse.json”,response.Content);
}
}
}

我正在使用自定义身份验证提供程序:

public class CustomCredentialsAuthProvider : CredentialsAuthProvider
{
    private readonly IUserService _userService;
    private Guid _userId;

    public CustomCredentialsAuthProvider ( Container container )
    {
        _userService = container.Resolve<IUserService>();
    }

    public override bool TryAuthenticate ( IServiceBase authService, string email, string password )
    {
        var user = _userService.GetByEmailAddress( email );
        user.Password = password; // Add the posted password to the user object before authenticating.

        _userId = user.Id;
        return _userService.CheckPassword( user );
    }

    public override void OnAuthenticated ( IServiceBase authService, IAuthSession session, IOAuthTokens tokens, Dictionary<string, string> authInfo )
    {
        session.Id = _userId.ToString();

        //Important: You need to save the session!
        authService.SaveSession( session, SessionExpiry );
    }
}

进一步开发,调用以下代码确实会为用户返回true,但显然不会将会话数据传递给后续的
RestRequest

// Calling this returns TRUE for TryAuthenticate
// But doesn't retain the session data for the subsequenet request.
var container = EndpointHost.AppHost.TryResolve<Container>();
var authService = new AuthService();
var customCredentialsAuthProvider = new CustomCredentialsAuthProvider( container );
customCredentialsAuthProvider.TryAuthenticate(authService, _testLoginEmail, _testLoginPassword);
//调用此函数将为TryAuthenticate返回TRUE
//但不保留后续请求的会话数据。
var container=EndpointHost.AppHost.TryResolve();
var authService=new authService();
var customCredentialAuthProvider=新的customCredentialAuthProvider(容器);
CustomCredentialAuthProvider.TryAuthenticate(authService、_TestLoginMail、_testLoginPassword);

因此,解决这个问题的最佳方法是使用
CookieContainer
并将其作为客户端的一部分传递

首先,我们为ServiceInterfaceTests创建了一个基类

public class ServiceInterfaceTestBase
{
    protected  IRestClient Client;
    protected void AuthenticateClient(string email, string password)
    {

        Client = new RestClient( ServiceTestAppHostBase.BaseUrl );
        var login = new RestRequest( "/auth", Method.POST );
        login.AddParameter( "username", email );
        login.AddParameter( "password", password );

        var response = Client.Execute( login );
        var cookieJar = new CookieContainer();

        if ( response.StatusCode == HttpStatusCode.OK )
        {
            var cookie = response.Cookies.FirstOrDefault();
            cookieJar.Add( new Cookie( cookie.Name, cookie.Value, cookie.Path, cookie.Domain ) );
        }

        Client.CookieContainer = cookieJar;  
    }
}
ServiceInterfaceTests从中继承

[TestFixture]
public class UserServiceInterfaceTests : ServiceInterfaceTestBase
{
然后在我们的设置中,我们调用auth方法

[SetUp]
public void SetUp ()
{
    _restSchemaValidator = new RestSchemaValidator();
    _testLoginEmail = UserFixture.SystemAccount.Email;
    _testLoginPassword = "password"; // the database contains a hashed password version of "password".

  AuthenticateClient(_testLoginEmail, _testLoginPassword);
}
最后,我们的测试看起来像

[Test]
public void ShouldGetAListOfUsersAndReturnStatusOk ()
{
    // Setup
    var request = new RestRequest( "/users/", Method.GET ) { RequestFormat = DataFormat.Json, };

    // Execute
    var response = Client.Execute( request );

    // Assert
    Assert.That( response.ErrorMessage, Is.Null );
    Assert.That( response.StatusCode, Is.EqualTo( HttpStatusCode.OK ) );
    _restSchemaValidator.ValidateResponse( "ExpectedUsersResponse.json", response.Content );
    Trace.Write( response.Content );
}

似乎无法发现此代码的任何问题。您正在以与我们相同的方式设置
client.Authenticator
,并注册您的
AuthFeature
和自定义auth提供程序对象。你能在
TryAuthenticate
中设置断点吗?@esker
TryAuthenticate
甚至没有被点击。我必须点击
auth?用户名吗=system@account.com&password=password
URL在测试设置中进行身份验证?实际上,我们的身份验证代码是一个自定义RequestFilterAttribute子类,不使用内置的AuthFeature功能,所以我不太了解它是如何工作的。很有趣,感谢您的浏览。我希望我能从这里ping@mythz,看看他要说什么。我不确定我必须连接什么才能启动
tryaauthenticate
[Test]
public void ShouldGetAListOfUsersAndReturnStatusOk ()
{
    // Setup
    var request = new RestRequest( "/users/", Method.GET ) { RequestFormat = DataFormat.Json, };

    // Execute
    var response = Client.Execute( request );

    // Assert
    Assert.That( response.ErrorMessage, Is.Null );
    Assert.That( response.StatusCode, Is.EqualTo( HttpStatusCode.OK ) );
    _restSchemaValidator.ValidateResponse( "ExpectedUsersResponse.json", response.Content );
    Trace.Write( response.Content );
}