在ASP.NET Web应用程序中隐藏queryString
我有两个Web应用程序,一个是简单的身份验证站点,它可以对登录的用户进行身份验证,然后将其重定向到另一个站点。
因此,我必须将the userId(GUID)传递给第二个应用程序。目前,这是通过URL完成的,但我想隐藏此ID。
有人知道如何正确执行此操作吗?
[编辑]:由于ApplicationBoundaries(2个不同的服务器),我无法使用会话
解决方案
通过会话传递GUID是最好的方法。
http://www.w3schools.com/ASP/asp_sessions.asp
或者,因为它是2个不同的服务器,所以通过POST方法传递信息:
http://www.w3schools.com/aspnet/aspnet_forms.asp
另一种可能性是将会话状态存储在本地服务器上的数据库中,并从另一台服务器远程访问该数据库,以查看用户是否已成功登录并在会话时限内。
考虑到这一点,我们也可以远程进行整个身份验证。从远程服务器远程连接到本地数据库并从那里检查登录凭据...这样,我们将能够在远程服务器上存储会话和/或者cookie。
我建议我们反对隐藏领域的主张,因为它完全抵消了我们正在尝试做的事情!我们试图在URL中隐藏GUID,但在HTML代码中发布相同的信息!这不是做到这一点的方法。
最好的选择是数据库选项,或者如果不可能,则使用HTTP POST。
使用会话变量或者HTTP POST代替HTTP GET。
如果服务器具有通用域名,则可以使用cookie。
编辑:Cookies只会在视觉上隐藏ID,仍然可以访问。与隐藏字段相同,或者使用POST而不是GET。因此,如果ID是可信的,并且我们希望避免通过未加密的网络发送它,则需要采用其他方法。
一种解决方案是使用服务器共享的密钥来加密身份验证服务器上的ID。另一种解决方案是在身份验证服务器上生成一个随机GUID,然后让身份验证服务器直接通过SSL通知另一服务器该GUID对应的ID。
而不是通过查询字符串传递它,我们应该创建一个带有其值的隐藏表单域,然后发布到第二页,该页面可以获取发布的值,并且对用户隐藏。
这听起来很棘手。
但是,我们可以使用几个选项,但这都取决于应用程序执行的操作。
让我们将WebApp1称为身份验证站点,将WebApp2称为远程站点经过身份验证之后。
WebApp2不能在后台调用WebApp1吗? (服务)
在应用程序之间传递此Guid的问题是它要经过明文显示,并考虑到它是一个用户ID,如果有人设法拦截到此,则他们将可以终身使用WebApp2. 无论我们将其传递给查询字符串还是形式变量,它仍然很容易受到攻击。
如果无法使用WebApp2查询WebApp1,则应考虑使用WebApp1创建一个到期的临时Guid。从长远来看,这样做会更安全,但是很明显,文本仍然容易受到攻击。 2个Web应用程序还将需要访问相同的数据存储。
最终,我认为认证站点应该是WebApp2可以使用的服务。
用户应通过WebApp2登录,WebApp2将安全地调用WebApp1进行身份验证。
然后,WebApp2可以管理自己的会话。
如果我们无法使用Cookie,因为它是跨域的,请使用随机数对其进行加密。
在两台服务器之间设置共享机密/密钥;将加密的GUID和随机数组合发送到第二台服务器。取消加密,检查尚未使用的随机数(以停止回复攻击),然后使用未加密的GUID。
如果我们想变得更棘手,可以在app1上使用一个Web服务来检查实际发出的随机数(此时,我们将转向WSTrust和单一登录解决方案,该解决方案通常可以解决我们要执行的操作)
即使使用cookie,因为它们很容易编辑/伪造,我们也应该进行某种形式的检查。
我们有两个ASP.NET Web应用程序,而一个应用程序除了对用户进行身份验证外什么都不做?
这听起来像是...的工作。
在身份验证应用程序上创建一个新的Web服务(它们是.asmx扩展名),并添加一个接受用户和密码等并返回身份验证信息的方法。
然后在第二个应用程序上导入WSDL,然后像调用方法一样调用第一个应用程序。它将简化代码,并解决问题。
一个例子:
AuthenticateUserService.asmx进入身份验证应用程序:
using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class AuthenticateUserService : System.Web.Services.WebService { [WebMethod] public bool AuthenticateUser(string username, string passhash) { // Fake authentication for the example return (username == "jon" && passhash == "SomeHashedValueOfFoobar"); } }
设置完成后,启动主应用程序,然后右键单击该项目,然后单击"添加Web参考"。
在身份验证应用程序上输入asmx的url,Visual Studio会发现它并创建一个代理类。
完成此操作后,我们可以像在主应用程序中将其作为本地方法一样调用该方法:
protected void Page_Load(object sender, EventArgs e) { // Now we can easily authenticate user in our code AuthenticateUserService authenticationProxy = new AuthenticateUserService(); bool isUserAuthenticated = authenticationProxy.AuthenticateUser("jon", SomeHashMethod("foobar")); }
那么,这到底是做什么的呢?
它将客户端从身份验证过程中消除了。
我们当前的流程:
- 客户输入AppA的凭据
- AppA将客户端重定向到AppB
- 如果凭据匹配,则AppB将客户端重定向回AppA。
由AppA和AppB之间的服务器端SOAP调用代替。现在它是这样的:
- 客户在AppA中输入凭据
- AppA询问AppB是否良好
- AppA为客户提供适当的内容。
进行会话管理或者使用上述帖子中所述的HTTP帖子。