I have been assigned with a task to restrict multiple simultaneous usages of a silverlight application for a single user. Ideally each time user opens new application, previous instance should receive some sort of notification and shut down.
我被分配了一个任务来限制一个用户同时使用silverlight应用程序。理想情况下,每次用户打开新应用程序时,以前的实例都应该收到某种通知并关闭。
Silverlight application consumes data using WCF services exposed via REST endpoint. Currently every call to the service has username and password as parameters. This was good because we were having stateless services. There are some apps which use these services already, and I am looking for the least painful solution.
Silverlight应用程序使用通过REST端点公开的WCF服务来使用数据。目前,每个对服务的调用都有用户名和密码作为参数。这很好,因为我们有无状态的服务。有一些应用已经在使用这些服务,我正在寻找最不痛苦的解决方案。
Thanks
谢谢
2 个解决方案
#1
2
Ok, so I rushed in to answer because I misunderstood the question. I initially thought you were referring to instances on the same computer.
好吧,我赶紧回答,因为我误解了这个问题。我最初以为你指的是同一台电脑上的实例。
For preventing multiple instances on the same computer you can use the LocalMessageReceiver Class.
为了防止同一台计算机上的多个实例,您可以使用LocalMessageReceiver类。
You can see a code example here that shows you how to prevent the user from opening a second instance of the application. Each LocalMessageReceiver must have a unique channel name as a constructor parameter. If the constructor throws an exception you can assume that there is another instance of the application.
您可以在这里看到一个代码示例,它向您展示如何防止用户打开应用程序的第二个实例。每个LocalMessageReceiver必须有一个唯一的通道名作为构造函数参数。如果构造函数抛出异常,则可以假定应用程序有另一个实例。
If you want to keep only the last application instance and close the previous ones, then you should create unique channel names for each instance and then dispatch a message to tell the other instances to close.
如果您只想保留最后一个应用程序实例并关闭前一个实例,那么您应该为每个实例创建惟一的通道名称,然后发送消息通知其他实例关闭。
For preventing multiple instances of the application on different computers I'm less qualified to answer, but the first thing that comes to mind is writing in the database whenever a user logs in..
为了在不同的计算机上防止应用程序的多个实例,我不太有资格回答,但我首先想到的是,每当用户登录时都要在数据库中写入。
If your services don't necessarily have to remain stateless then you can keep in a database table a unique identifier for each time a user logs in (ex: the login date?), and then whenever the user wants to do some action, you can check if the last identifier from the database corresponds to the one you have in the current session. If not, it means someone logged in with the same user from another computer, so you can expire the session.
如果你的服务不一定必须保持无状态可以保持在一个数据库表中一个独特的标识符每次用户登录(例:登录日期吗?),然后每当用户想要做一些行动,您可以检查,如果最后从数据库标识符对应的当前会话。如果不是,则意味着某人从另一台计算机登录了相同的用户,因此您可以使会话过期。
#2
1
Because Silverlight itself is not a stateless application, you should be able to implement this with a simple service and HMAC. If you have the usernames and/or guids in your database already, it should be a simple addition to have a singular table keyed of the user's guid that contains some timestamp information and a specific HMAC for a particular login. This HMAC would be generated from something specific about the machine in conjunction with the timestamp it was being generated. Something like:
因为Silverlight本身不是一个无状态的应用程序,所以您应该能够通过一个简单的服务和HMAC实现它。如果您已经在数据库中拥有用户名和/或gui,那么只需添加一个单独的表,该表对用户的guid进行键控,其中包含一些时间戳信息和特定的用于特定登录的HMAC。这个HMAC将与正在生成的时间戳一起,由关于机器的特定内容生成。喜欢的东西:
userGuid | activeHMAC | lastLoginDate | currentlyLoggedIn (bit)
Then on the login action of the silverlight control, a record for the userGuid can be added or updated to include the current information. This would force all new logins to overwrite existing login HMACs. Then on a logout or close event, simply call the service and set the currentlyLoggedIn
bit to false.
然后在silverlight控件的登录操作上,可以添加或更新userGuid记录,以包含当前信息。这将迫使所有的新登录都覆盖现有的登录hmac。然后,在注销或关闭事件上,只需调用服务并将currentlyLoggedIn位设置为false。
You would then need to ensure that this HMAC was sent with all communication to a web service so that it could be verified against new calls or have each client periodically call the service to compare the HMAC and disable the client if it fails the comparison. Since Silverlight runs in a disconnected fashion, your choice would probably be governed by data integrity. Personally, I think it would be safer to embed the HMAC into all communications to prevent any kind of lag time from allowing inappropriate actions.
然后,您需要确保这个HMAC与web服务的所有通信一起发送,以便可以根据新的调用对它进行验证,或者让每个客户端定期调用该服务来比较HMAC,并在该客户端失败时禁用该客户端。由于Silverlight以一种不连贯的方式运行,您的选择很可能受到数据完整性的控制。我个人认为,最好将HMAC嵌入到所有通信中,以防止任何形式的延迟时间允许不适当的操作。
#1
2
Ok, so I rushed in to answer because I misunderstood the question. I initially thought you were referring to instances on the same computer.
好吧,我赶紧回答,因为我误解了这个问题。我最初以为你指的是同一台电脑上的实例。
For preventing multiple instances on the same computer you can use the LocalMessageReceiver Class.
为了防止同一台计算机上的多个实例,您可以使用LocalMessageReceiver类。
You can see a code example here that shows you how to prevent the user from opening a second instance of the application. Each LocalMessageReceiver must have a unique channel name as a constructor parameter. If the constructor throws an exception you can assume that there is another instance of the application.
您可以在这里看到一个代码示例,它向您展示如何防止用户打开应用程序的第二个实例。每个LocalMessageReceiver必须有一个唯一的通道名作为构造函数参数。如果构造函数抛出异常,则可以假定应用程序有另一个实例。
If you want to keep only the last application instance and close the previous ones, then you should create unique channel names for each instance and then dispatch a message to tell the other instances to close.
如果您只想保留最后一个应用程序实例并关闭前一个实例,那么您应该为每个实例创建惟一的通道名称,然后发送消息通知其他实例关闭。
For preventing multiple instances of the application on different computers I'm less qualified to answer, but the first thing that comes to mind is writing in the database whenever a user logs in..
为了在不同的计算机上防止应用程序的多个实例,我不太有资格回答,但我首先想到的是,每当用户登录时都要在数据库中写入。
If your services don't necessarily have to remain stateless then you can keep in a database table a unique identifier for each time a user logs in (ex: the login date?), and then whenever the user wants to do some action, you can check if the last identifier from the database corresponds to the one you have in the current session. If not, it means someone logged in with the same user from another computer, so you can expire the session.
如果你的服务不一定必须保持无状态可以保持在一个数据库表中一个独特的标识符每次用户登录(例:登录日期吗?),然后每当用户想要做一些行动,您可以检查,如果最后从数据库标识符对应的当前会话。如果不是,则意味着某人从另一台计算机登录了相同的用户,因此您可以使会话过期。
#2
1
Because Silverlight itself is not a stateless application, you should be able to implement this with a simple service and HMAC. If you have the usernames and/or guids in your database already, it should be a simple addition to have a singular table keyed of the user's guid that contains some timestamp information and a specific HMAC for a particular login. This HMAC would be generated from something specific about the machine in conjunction with the timestamp it was being generated. Something like:
因为Silverlight本身不是一个无状态的应用程序,所以您应该能够通过一个简单的服务和HMAC实现它。如果您已经在数据库中拥有用户名和/或gui,那么只需添加一个单独的表,该表对用户的guid进行键控,其中包含一些时间戳信息和特定的用于特定登录的HMAC。这个HMAC将与正在生成的时间戳一起,由关于机器的特定内容生成。喜欢的东西:
userGuid | activeHMAC | lastLoginDate | currentlyLoggedIn (bit)
Then on the login action of the silverlight control, a record for the userGuid can be added or updated to include the current information. This would force all new logins to overwrite existing login HMACs. Then on a logout or close event, simply call the service and set the currentlyLoggedIn
bit to false.
然后在silverlight控件的登录操作上,可以添加或更新userGuid记录,以包含当前信息。这将迫使所有的新登录都覆盖现有的登录hmac。然后,在注销或关闭事件上,只需调用服务并将currentlyLoggedIn位设置为false。
You would then need to ensure that this HMAC was sent with all communication to a web service so that it could be verified against new calls or have each client periodically call the service to compare the HMAC and disable the client if it fails the comparison. Since Silverlight runs in a disconnected fashion, your choice would probably be governed by data integrity. Personally, I think it would be safer to embed the HMAC into all communications to prevent any kind of lag time from allowing inappropriate actions.
然后,您需要确保这个HMAC与web服务的所有通信一起发送,以便可以根据新的调用对它进行验证,或者让每个客户端定期调用该服务来比较HMAC,并在该客户端失败时禁用该客户端。由于Silverlight以一种不连贯的方式运行,您的选择很可能受到数据完整性的控制。我个人认为,最好将HMAC嵌入到所有通信中,以防止任何形式的延迟时间允许不适当的操作。