我有一个ASP.NET MVC(非ASP.NET核心)单页面应用程序,前端有角度js.
我的客户端(浏览器)通过ASP.NET Web API与服务器通信.现在,Web应用程序是https但匿名.没有登录/用户身份验证.
Web应用程序采用向导的形式,用户可以来回移动并在网页上添加或更新输入字段.然后,通过Web API在服务器上更新表单输入值.
我正在寻找一种方法来保护我的Web API调用,尤其是POST/PUT请求.总之,我想阻止任何用户直接从POSTMAN或Fiddler调用我的Web API.Web API虽然是匿名的,但只能从发出请求的浏览器会话中调用.
我有什么选择来实现这一目标?
我可以在这里使用Anti-Forgery令牌(无需身份验证)吗?
一种方法,我可以想到实现这一点是为每个请求添加一个自定义标头,并在标头中存储某种会话密钥.然后,在我从客户端收到的每个请求上验证自定义标头.有没有其他方法可以实现这个开箱即用或一些经过验证的库而无需自定义解决方案?
如果我必须采用上述自定义解决方案,我需要注意哪些陷阱或潜在问题?
我们最近将使用的 ASP.NET Core API 迁移Dapper到 .NET Core 3.1。迁移后,我们觉得有机会为我们的一个端点使用最新IAsyncEnumerable功能C# 8。
这是更改前的伪代码:
public async Task<IEnumerable<Item>> GetItems(int id)
{
var reader = await _connection.QueryMultipleAsync(getItemsSql,
param: new
{
Id = id
});
var idFromDb = (await reader.ReadAsync<int?>().ConfigureAwait(false)).SingleOrDefault();
if (idFromDb == null)
{
return null;
}
var items = await reader.ReadAsync<Item>(buffered: false).ConfigureAwait(false);
return Stream(reader, items);
}
private IEnumerable<Item> Stream(SqlMapper.GridReader reader, IEnumerable<Item> items)
{
using (reader)
{
foreach (var item in items)
{
yield return item;
}
}
}
Run Code Online (Sandbox Code Playgroud)
之后 …
请检查以下代码:
objDDLTable = HttpContext.Current.Cache["TestSet"] as Hashtable;
if (objDDLTable == null)
{
objDDLTable = new Hashtable();
arrDDLItems = GetDropDownList("testDropDown");
objDDLTable.Add("testDropDown", arrDDLItems);
HttpContext.Current.Cache["TestSet"] = objDDLTable;
}
else if (objDDLTable != null && !objDDLTable.Contains("testDropDown"))
{
arrDDLItems = GetDropDownList("testDropDown");
objDDLTable.Add("testDropDown", arrDDLItems);
HttpContext.Current.Cache["TestSet"] = objDDLTable;
}
else
{
arrDDLItems = objDDLTable["testDropDown"] as DdlItem[];
}
Run Code Online (Sandbox Code Playgroud)
您可以推断,代码基本上是为网页上的下拉列表缓存一些值.
首先,它尝试从缓存中读取HashTable对象,然后检查从缓存中读取的HashTable对象中是否存在特定键.如果是,则读取值(项目数组),否则,它从源读取数组并在HashTable中添加新密钥,然后将其存储回缓存以供后续使用.
这在大多数情况下都可以正常工作,但是,我们偶尔会遇到以下错误:
System.ArgumentException: Item has already been added.
Key in dictionary: 'testDropDown' Key being added: 'testDropDown' at
System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add) at
System.Collections.Hashtable.Add(Object key, Object value)
Run Code Online (Sandbox Code Playgroud)
从逻辑上讲,系统testDropDown …
我们的团队正在按照领域驱动设计 (DDD) 启动一个新项目。在高层次上,我们在域的顶部有一个 API,它使客户端能够在域上执行操作。我不太清楚的问题之一是我们在哪里对 DDD 中的某个属性/属性执行验证。
考虑这个例子。让我们说,我的 API 公开了以下数据合同/ DTO:
public class Person
{
public string Email { get; set;}
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在,假设我们有业务验证,可以防止用户输入无效的电子邮件地址并限制用户的姓名超过 50 个字符。
为此,我可以看到以下三种方法:
在方法 1 中,我们仅在 API 上进行数据验证(通过数据注释或 Fluent 验证)。我不会在我的域中重复验证。从理论上讲,这可能意味着我的域可能处于无效状态。但是,由于入口点 (API) 正在验证,因此在实际场景中是不可能的。
在方法 2 中,我们在 API 和我的域中进行数据验证。这种方法帮助我们完全消除了我的域和 API 之间的耦合。API 可以独立向客户端返回 Bad 请求。并且由于域再次执行验证,域不可能进入无效状态。然而,在这种方法中,我们违反了 DRY 原则。
在方法 3 中,我们只在 Domain 进行验证,而不在 API 级别对 DTO 进行验证。使用这种方法,虽然我们不重复验证,但当 API 调用试图将域置于无效状态时,域不会抛出异常。相反,我们需要将该异常包装在某个Result对象中。这将有助于 API 向客户端发送适当的响应(例如,错误请求而不是内部服务器错误)。我不喜欢这种方法的一点是我更愿意抛出一个硬异常而不是放置一个包装器。

问
哪种方法最有意义,为什么?
业务验证和业务规则之间的界限在哪里?(假设业务规则存在于域中)。
有什么明显的东西我在这里遗漏了吗?
注意:这个问题可能看起来类似于 域驱动设计中的验证, …
我们使用Team City(版本2017.1.5)建立了构建管道,并且我们使用内部Bitbucket服务器(版本4.8)作为我们的git存储库.我们的分支模型是GitHub Flow
我们使用mendhak Team City插件向Bitbucket服务器报告构建状态.此外,我们已经在团队城市中创建了一个构建来构建具有分支触发器的拉取请求:+:refs/(pull-requests/*)/merge.
但是,此分支过滤器的构建状态在拉出请求窗口/页面的Bitbucket中不可见.
如果我们在特征分支上使用分支过滤器(例如+:refs/heads/(feature/*)),则在PR上正确显示构建状态.但是,我们有兴趣在Pull Request上显示PR构建状态.
我们发现自2013年以来Atlassian 已经存在一个未解决的问题(是的 - 差不多5年).看起来它不会很快修复.
问:
是否有任何可以解决此问题的变通方法或Bitbucket插件(或Team City插件).我们希望避免添加任何额外的分支过滤器/触发器.
我觉得这是一个相当普遍的问题,应该已经被很多其他团队/个人解决了.我恰好没有找到合适的资源/材料.
任何指针,都非常感谢.
我们正在寻找一种方法来跨多个API请求Request-Id(一个或Correlation-Id多个),如下图所示:
这个想法是有一个单一的ID来通过我们日志中的多个API跟踪特定的请求。我们使用ILogger的是.NET Core 2.1随附的标准。
到目前为止我们尝试过的
我们尝试Request-Id在请求标头中使用,成功记录了日志,但是我们无法检索该值以将其添加到其他API的后续HTTP请求中。
我们注意到,还有一个CorrelationId被记录下来。但是,我们不知道如何更新它。
此外,我们注意到有TraceIdentity可在HttpContextAccessor这有可能解决我们的宗旨。但是,我们不知道如何利用它来解决我们的问题。
我们无法使用Application Insights,而是要依赖我们自己的日志记录基础结构框架。我们在文档中找不到太多内容。
是否有可用的现成解决方案可供我们使用,而无需提出自己的自定义解决方案?
我们使用在 ASP.NET Core 2.2 上运行的 Web API设置集成测试xUnit并Microsoft.AspNetCore.TestHost.TestServer运行测试。
我们的 Web API 是一个单一的代码库,可以根据一些配置或应用程序设置差异(如国家、货币等)单独部署多次。
下图试图解释我们的部署设置:
我们希望确保我们的集成测试针对所有部署运行。
对于这两种部署,X和X` API 端点、请求和响应完全相同。因此,当涉及到每个部署的集成测试时,我们希望避免重复自己。
以下是解释我们当前测试设置的示例代码:
TestStartup.cs
public class TestStartup : IStartup
{
public IServiceProvider ConfigureServices(IServiceCollection services)
{
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", false)
.AddEnvironmentVariables()
.Build();
services.AddMvc()
.SetCompatibilityVersion(version: CompatibilityVersion.Version_2_2);
// Code to add required services based on configuration
return services.BuildServiceProvider();
}
public void Configure(IApplicationBuilder app)
{
app.UseMvc();
// Code to configure test Startup
}
}
Run Code Online (Sandbox Code Playgroud)
TestServerFixture.cs …
我正在使用一个Web应用程序,它是MVC 5 + Angular JS混合.有没有身份验证的Web应用程序和匿名用户可以来问价格的某些服务.为了获得价格,用户需要回答几页中的一些问题.这是app的流程.
用户点击按钮获取价格
生成请求的唯一URI,用户将重定向到问题页面
用户回答问题,用户提交答案.问题分布在通过角度路由导航的多个页面上.答案将在页面导航中保存回服务器.
一旦用户提交答案,系统(服务器)就会生成价格并将其显示给用户.
目前,如果用户已经为URI添加了书签,他可以在几天之后返回,并从他离开的地方继续.我想阻止这种行为.
我在MVC中有哪些不同的选择?我可以想到以下几点:
使用HttpCookie有效期
保存数据库中的最后访问时间并验证用户是否已达到规定的时间范围内?
我想避免HttpSession.我倾向于使用,HttpCookie因为它看起来是最简单的选择.
如果我们HttpCookie选择,是否有任何副作用,我需要记住?
我可以在MVC中找到其他替代方案吗?
我在使用Visual Studio中的Docker运行构建在ASP.NET Core上的应用程序时遇到问题.我的应用程序只使用dnxcore50框架.我的project.json文件是:
{
"version": "1.0.0-*",
"compilationOptions": {
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
"Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
"Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
"Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final"
},
"frameworks": {
"dnxcore50": { }
},
"exclude": [
"wwwroot",
"node_modules"
],
"publishExclude": [
"**.user",
"**.vspscc"
],
"commands": {
"web": "Microsoft.AspNet.Server.Kestrel"
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试了以下方法:
我的应用程序成功构建 但是,我在docker上运行/调试应用程序时遇到以下错误,我的应用程序卡在"打开站点http://192.168.99.100:5000 "

错误详细信息: 当前运行时框架与'app'不兼容当前运行时目标框架:'DNX,Version = v4.5.1(dnx451)'请确保运行时与project.json中指定的框架匹配
dnvm use default -p.然后,我重启我的VS(以确保在VS中可以看到更改).但是,我的应用程序仍然建立在DNX版本v4.5.1上,如下面的构建日志中所示:
1> Information: [LoaderContainer]: Load name=Microsoft.Dnx.Tooling
1> Information: [PathBasedAssemblyLoader]: Loaded name=Microsoft.Dnx.Tooling in 2ms
1> Information: …Run Code Online (Sandbox Code Playgroud) 我正在尝试为 COMOS 中的几个属性定义索引,但我对自动索引有点困惑。根据 Cosmos DB文档:
默认情况下,Azure Cosmos DB 会自动为容器中所有项目的每个属性编制索引,而无需定义任何架构或配置二级索引。
另外,请参考这个:
在某些情况下,您可能希望覆盖此自动行为以更好地满足您的要求。您可以通过设置容器的索引模式来自定义容器的索引策略,并包括或排除属性路径。
从以上几点我了解到,除非我们定义自定义索引策略,否则自动索引设置为true(这是有道理的)。但是,如果我们paths为索引定义了自己的包含和排除,否则它应该是false.
这可能意味着,如果我如下定义容器属性,则该Indexing Policy Automatic属性应false在 Cosmos DB 上设置为。
using Microsoft.Azure.Cosmos; //Azure Cosmos SDK v3.3.1
.
.
var containerProperties = new ContainerProperties
{
Id = "SOME_CONTAINER_NAME",
PartitionKeyPath = "/MY_PARTITION_KEY",
};
containerProperties.IndexingPolicy.IncludedPaths.Add(new IncludedPath {Path = "/\"{MY_PARTITION_KEY}\"/?"});
containerProperties.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath {Path = "/*"});
Run Code Online (Sandbox Code Playgroud)
但是,我看到 CosmosDb 索引的上述配置被定义为automaticset to true。

Automaticproperty 和IncludedPaths,ExcludedPaths属性是否IndexingPolicy class …
最近,我遇到了一个关于使用dynamicw的有趣问题。当我将dynamic对象作为参数传递时,无法推断该方法的返回类型。
这是最小的可重现示例:
此代码编译成功:
class Program
{
public static void Main()
{
dynamic data = new { SomeProperty = "ABC" };
string response = IsTrue(data);
if (response == "1")
{
Console.WriteLine("How can this compile?");
}
}
private static bool IsTrue(object someData)
{
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,IsTrue返回 abool但类型response不是推断为bool。结果,上面的代码编译成功。
在运行应用程序时,我得到以下运行时异常:
未处理的异常。Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:运算符“==”不能应用于 System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0 ,T1,TRet](CallSite 站点, T0 arg0, T1 arg1)
这怎么可能?
c# ×9
asp.net ×3
.net-core ×2
asp.net-core ×2
asp.net-mvc ×2
.net ×1
angularjs ×1
async-await ×1
azure ×1
bitbucket ×1
caching ×1
dapper ×1
docker ×1
git ×1
logging ×1
pull-request ×1
teamcity ×1
xunit ×1