问题描述
背景:
我们有一个 ASP.NET/Silveright Web 应用程序.Silverlight 客户端显示用户图形形式的特定数据 - 它从服务器请求数据:
We have an ASP.NET / Silveright web application. The silverlight client displays userspecific data in a graphical form - it requests the data from the server:
问题:由于服务器必须执行底层数据库查询,因此获取此数据的成本很高 - 因此客户端必须等待...
Problem:Getting this data is expensive, due to the underlying database queries that the server has to perform - so the client has to wait...
优化思路:我们定期在服务器上运行数据库查询,将结果写入靠近 ASP.NET 服务器运行位置的数据库中的userdata"表.
Optimisation Idea:We run the database queries at regular intervals on the server, writing the results to a'userdata' table in a database 'close' to where the ASP.NET server runs.
运行查询并将数据写入表的过程是由与 ASP.NET 服务器分离的数据收集"服务执行.
The process of running the queries and writing the data to the tables isperformed by a 'data collection' service, which is separated from the ASP.NET server.
当客户端请求数据时,服务器从用户数据"表中检索它.这应该很好而且很快——我们可能在与 ASP.NET 服务器相同的机器上有userdata"表.我们还有一个额外的好处,即使底层数据库离线,客户端也能看到数据.
When the client requests data the server retrieves it from a 'userdata' table.This should be nice and quick - we probably have the 'userdata' tables on the same machine as the ASP.NET server. We also have the added benefit that the client sees data even if the underlying database is offline.
当然,数据不是实时的 - 但所有数据一旦到达客户端就可能是旧的.
Of course the data is not live - but all data is potentially old as soon as it reaches the client.
所以现在我的问题是:数据收集"服务需要用户凭据才能执行这些数据库查询(因为每个用户对同一个查询得到不同的结果).
So now my Problem:The 'data collection' service needs the user credentials in order to perform these databasequeries (because each user gets different results for the same query).
问题:
如何以可接受的安全"方式将用户凭据存储在数据库中?这样数据收集"就可以冒充用户来执行数据库查询.我们的初始场景基于使用 Windows 集成登录数据库.
How can I store user credentials in a database, in an acceptable 'secure' way?Such that the 'data collection' can impersonate a user to perform the database queries.Our initial scenario is based upon using windows integrated login to the database.
推荐答案
据我所知,您需要为每个用户运行一个查询,但您不想使其成为阻塞调用.您需要非规范化读取模型 UserData 的响应能力.
As I understand this you will need to run a query per user but you do not want to make this a blocking call. You want the responsiveness of a denormalized read model, the UserData.
我有一个想法,您无需将凭据存储在某处,而只需启动一个线程并为该线程提供从请求中获取的当前凭据.
I have an idea where you instead of storing the credentials somewhere, you simply start a thread and provide that thread with the current credentials taken from the request.
class MyClass
{
public static void DoSomething(object principal)
{
if (principal == null || !(principal is IPrincipal))
throw new ArgumentException();
Thread.CurrentPrincipal = (IPrincipal) principal;
// Do heavy querying and update UserData
}
}
我从这样的 ASP.NET MVC 控制器中调用它:
I call this from an ASP.NET MVC Controller like this:
public ActionResult Index()
{
var t = new Thread(MyClass.DoSomething);
t.Start(User);
return View();
}
这将更新每个请求的 UserData.如果需要,您可以为更新频率引入一些逻辑,并且仅在特定条件下进行调用.
This would update the UserData for each request. If you want, you could introduce some logic for the update frequency and only make the call on certain conditions.
我正在考虑的另一种方法是迈向 CQRS 思维模式的一步,在这种情况下,我将发布一条包含序列化 IPrincipal
的消息,该消息将被另一个实例/服务器使用将读取模型更新为一个单独的过程.但我不确定如果在另一台服务器上反序列化 IPrincipal
是否真的可以工作.
Another approach I was thinking about was a step towards the CQRS mindset, where I in this case would publish a message containing the serialized IPrincipal
and that message would be consumed by another instance/server that would update the read model as a separate process. But I am uncertain that the IPrincipal
would actually work if deserialized on another server.
无论如何,我看不到保留凭据的好处.只需在新线程的范围内或在使用的消息的上下文中使用它们即可.
Anyway, I don't see the benefit of persisting the credentials. Just use them in the scope of a new thread or in the context of a message consumed.
这篇关于如何在服务器上保存用户凭据以在后台运行查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!