- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我目前正在编写一些单元测试来检查我们编写的 ASP MVC 应用程序的功能和正确工作。在此 MVC 应用程序中,我使用了一个特殊的 ActionFilterAttribute,它允许在向 MVC 应用程序发出请求时进行身份验证。
这个 ActionFilterAttribute 的代码是这样的:
using System;
using System.Security.Authentication;
using System.Text;
using System.Web.Mvc;
using TenForce.Execution.Framework;
using TenForce.Execution.Api2.Implementation;
namespace TenForce.Execution.Web.Filters
{
/// <summary>
/// This class defines a custom Authentication attribute that can be applied on controllers.
/// This results in authentication occurring on all actions that are beeing defined in the controller
/// who implements this filter.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AuthenticationFilter : ActionFilterAttribute
{
#region IAuthorizationFilter Members
/// <summary>
/// This function get's called by the Mvc framework prior to performing any actions on
/// the controller. The function will check if a call is authorized by the caller.
/// The function will extract the username and password from the HTTP headers send by
/// the caller and will validate these against the database to see if there is a valid
/// account for the user.
/// If the user can be found in the database, operations will resume, otherwise the action
/// is canceled.
/// </summary>
/// <param name="filterContext">The context for the filter.</param>
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Call the base operations first.
base.OnActionExecuting(filterContext);
// Surround the entire authentication process with a try-catch to prevent errors from
// breaking the code.
try
{
// Extract the custom authorization header from the HTTP headers.
string customAuthHeader = Encoding.UTF8.GetString(Convert.FromBase64String(filterContext.RequestContext.HttpContext.Request.Headers["TenForce-Auth"]));
// Split the header in the subcomponents.
string[] components = customAuthHeader.Split('|');
// Check if both components are present.
if (components.Length >= 2)
{
// This header consists of 2 parts, the username and password, seperate by a vertical pipe.
string username = components[0] ?? string.Empty;
string password = components[1] ?? string.Empty;
string databaseId = Authenticator.ConstructDatabaseId(filterContext.HttpContext.Request.RawUrl);
// Validate the user against the database.
if (Authenticator.Authenticate(username, password, databaseId))
{
// The request is valid, so add the custom header to inform the request was
// authorized.
AllowRequest(filterContext);
return;
}
throw new InvalidCredentialException(@"The provided username & password combination is invalid. Username : " + username);
}
// If we reach this point, the authorization request is no longer valid.
throw new InvalidCredentialException(@"Insufficient parameters supplied for a valid authentication.");
}
catch (Exception ex)
{
// Log the exception that has occurred.
Logger.Log(GetType(), ex);
// Cancel the request, as we could not properly process it.
CancelRequest(filterContext);
}
}
#endregion
#region Private Methods
/// <summary>
/// Cancels the Athorization and adds the custom tenforce header to the response to
/// inform the caller that his call has been denied.
/// </summary>
/// <param name="authContext">The authorizationContxt that needs to be canceled.</param>
private static void CancelRequest(ActionExecutingContext authContext)
{
authContext.Result = new HttpUnauthorizedResult();
if (!authContext.RequestContext.HttpContext.Request.ServerVariables[@"SERVER_SOFTWARE"].Contains(@"Microsoft-IIS/7."))
authContext.HttpContext.Response.AddHeader(@"Tenforce-RAuth", @"DENIED");
else
authContext.HttpContext.Response.Headers.Add(@"Tenforce-RAuth", @"DENIED");
}
/// <summary>
/// Allows the Authorization and adds the custom tenforce header to the response to
/// inform the claler that his call has been allowed.
/// </summary>
/// <param name="authContext">The authorizationContext that needs to be allowed.</param>
private static void AllowRequest(ActionExecutingContext authContext)
{
authContext.Result = null;
if (!authContext.RequestContext.HttpContext.Request.ServerVariables[@"SERVER_SOFTWARE"].Contains(@"Microsoft-IIS/7."))
authContext.HttpContext.Response.AddHeader(@"Tenforce-RAuth", @"OK");
else
authContext.HttpContext.Response.Headers.Add(@"Tenforce-RAuth", @"OK");
}
#endregion
}
}
我目前面临的问题是我似乎无法使用响应 header 正确模拟该部分。我编写了一个模拟 HttpRequest 和 HttpResponse 对象并使用请求调用属性函数的 UnitTest。我可以在 IIS7 模拟的代码中遵循成功的登录路径分支,因为这依赖于属性,但是当我尝试在登录中遵循 IIS6 分支时,我遇到了空指针异常。
我使用以下代码构造 MoQ 对象:
/// <summary>
/// This function is called before running each test and configures the various properties
/// of the test class so that each test will run with the same settings initialy.
/// The function will configure the Mock Framework object so that they simulate a proper
/// web request on the ActionFilter of a Controller.
/// </summary>
[SetUp]
protected void TestSetup()
{
// Construct the Mock object required for the test.
HttpRequest = new Mock<HttpRequestBase>();
HttpResponse = new Mock<HttpResponseBase>();
HttpContext = new Mock<HttpContextBase>();
ActionContext = new Mock<ActionExecutingContext>();
Filter = new Web.Filters.AuthenticationFilter();
// Configure the properties to modify the headers, request and response
// objects starting from the HttpContext base object.
// Also create the custom header collection and set the test URI.
ActionContext.SetupGet(c => c.HttpContext).Returns(HttpContext.Object);
HttpContext.SetupGet(r => r.Request).Returns(HttpRequest.Object);
HttpContext.SetupGet(r => r.Response).Returns(HttpResponse.Object);
HttpResponse.SetupGet(x => x.Headers).Returns(new System.Net.WebHeaderCollection());
HttpRequest.SetupGet(r => r.RawUrl).Returns(@"http://test.tenforce.tst");
}
实际测试是这样的:
/// <summary>
/// <para>This test will call the ActionFilter and perform a standard authorization request against the
/// database using the credentials of the system administrator account. The test relies on the MoQ
/// framework to mock several of the key components in the MVC Framework such as the HttpRequest,
/// HttpResponse and HttpContext objects.</para>
/// <para>The test expects the authentication to succeed, and relies on the IIS6 implementation.</para>
/// </summary>
[Test, MaxDuration]
public void SuccessfullAuthenticationOnIis6()
{
// Configure the Authentication header of the request, so that a valid authentication
// can take place. We want valid login credentials when the filter requests the header.
HttpRequest.SetupGet(r => r.Headers).Returns(new System.Net.WebHeaderCollection { { @"TenForce-Auth", CorrectAuthToken } });
HttpRequest.SetupGet(r => r.ServerVariables).Returns(
new System.Collections.Specialized.NameValueCollection { { @"SERVER_SOFTWARE", @"Microsoft-IIS/6.0" } });
HttpResponse.SetupGet(r => r.Headers).Returns(new System.Collections.Specialized.NameValueCollection());
HttpResponse.Setup(r => r.AddHeader(@"TenForce-RAuth", @"OK"));
// Call the action on the filter and check the response.
Filter.OnActionExecuting(ActionContext.Object);
// Check the ActionResult to null and that the response header contains the correct value.
Assert.IsTrue(ActionContext.Object.Result == null);
Assert.IsTrue(ActionContext.Object.HttpContext.Response.Headers["TenForce-RAuth"].Equals(@"OK"));
}
最后一个断言失败,因为没有设置 header 。我已经使用调试器单步执行代码并且过滤器确实设置了 header ,所以我认为 MoQ 对象没有正确配置来处理请求。
有人可以阐明我如何让我的 HttpResponse 接受 Headers.Add() 请求吗?
最佳答案
看来我找到了。我必须将以下行添加到我的设置中以将最小起订量的调用委托(delegate)给实现:
HttpResponse.Setup(r => r.AddHeader(It.IsAny<string>(), It.IsAny<string>())).Callback<string, string>((x,y) => HttpResponse.Object.Headers.Add(x, y));
很简单,但你必须知道...
关于c# - 模拟 MVC 应用程序的 HttpRequest 和 HttpResponse,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4732870/
假设我的客户端(浏览器)请求我的 java 服务(服务 A)。 http://localhost:8080/getDataFromB 根据服务 A 的请求,我需要向服务 B 或服务 C 发出另一个 H
我正在尝试调用 API 来检索数据列表,此数据将帮助我获取图像源。因此,对于每个数据条目,我尝试调用图像 url 并使用 Parse Image 进行一些图像处理。问题是,内部的 httpReques
当前代码 if (!(context.Exception is exception)) HttpContent requestContent = context.Request.Content
我有这个代码: You are browsing this site with: Or with Request.UserAgent: 第一个在浏览器
我正在使用 Django 和 TornadIO2/Tornado 编写一个 socket.io 应用程序。在 TonradIO2 session 中,我可以访问 Tornado 的 HTTPReque
用于确定用户代理的这两个属性之间有什么区别(如果有)和优点/缺点? Dim strUserAgt as String userAgent = Request.userAgent 对比 Dim strU
详情如下:https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.httprequest?view=aspnetco
我一直在关注我网站的性能,在所有执行缓慢的代码 (>1s) 中,超过 90% 是因为 System.Web.HttpRequest.GetEntireRawContent()(由 System.Web
我有一个后端服务,它接受授权 header 来验证访问。我使用 Spring cloud zuul 创建了一个网关服务,并将请求路由到后端服务。 网关服务本身受 OAuth2 保护,并接受授权 hea
是否可以在中间件函数中获取请求方法(GET、POST、PUT...)? $myMiddleware = function (Request $request) { // This is wha
代码如下: //Get请求方式 private string RequestGet(string Url) &n
在 .net Framework yield ok. // if is not valid var request = HttpContext.Current.Req
在用于 http get 和 post 的 angular 5.2.x 中,我有以下代码: post(url: string, model: any): Observable { return thi
我试图了解如何从Dart进行Ajax调用。我对Web编程的了解非常有限。 我的简单服务器ajax.py:- #!/usr/bin/env python from datetime import tim
我正在为Http GET请求创建包装器类,但是当我使用HttpRequest.request时,没有任何响应。如果我使用原始的HttpRequests使用等效的代码,则可以使用。 我想念什么吗?我正在
我正在尝试生成一个 jmeter 脚本,其中每次运行脚本时都会创建一个唯一的文件夹 - 将某种变量添加到文件夹名称中,例如用户名+时间戳,应该足以保证唯一性。然而,jmeter 并没有将变量解析为其值
我有一个网络应用程序,它有一个计时器,每 3 秒触发一次轮询以获取数据。它工作正常大约 2.5 分钟,然后 Chromium 崩溃。 我的请求 Dart 看起来像这样 HttpRequest.getS
我目前有一个函数,可以生成 httpRequest 并将接收到的 json 解析为 URL array 。我想在第一个请求完成并且数据解析后触发第二个 httpRequest ,在我尝试过的两种解决方
我试图像这样延迟我的 $http 调用: githubService.getUserEvents = function getUserEvents() { return $timeout
我正在运行 340 个并发用户以使用 jmeter 在服务器上进行负载测试。 但是在大多数情况下,jmeter 挂断并且不会返回,即使我尝试关闭连接它也只是挂断了。最终我不得不关闭应用程序。 任何想法
我是一名优秀的程序员,十分优秀!