C# 如何让ServiceStack测试使用RestSharp进行身份验证?
我在ServiceStack应用程序中实现了CustomCredentialAuth的工作实现。我可以用身份验证凭据点击URL,它可以按预期工作 然而,在我的测试中,我的运气不一样 我正在使用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
[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
中设置断点吗?@eskerTryAuthenticate
甚至没有被点击。我必须点击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 );
}