我想在Ajax上使用webservices。使用ajax调用webservice时,安全性的最佳方法是什么?我想防止远程呼叫退出应用程序。
我有以下 webservice ,例如:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class Users : System.Web.Services.WebService
{
[WebMethod]
public List<User> GetUsers()
{
List<User> listUsers = new List<User>();
User user = new User();
user.Id = 1;
user.Name = "John";
User user2 = new User();
user2.Id = 2;
user2.Name = "Martin";
listUsers.Add(user);
listUsers.Add(user2);
return listUsers;
}
}
}
我用jquery ajax调用webservice:
<script type="text/javascript">
$(function () {
getUsers();
function getUsers() {
$.ajax({
type: "POST",
url: "Webservices/Users.asmx/GetUsers",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
var users = response.d;
$.each(users, function (index, user) {
console.log(user.Name);
});
},
failure: function (msg) {
}
});
}
});
</script>
答案 0 :(得分:9)
没有最好的方式,答案总是it depends
,尽管它非常无益。例如,您可以使用forms authentication。如果使用Web服务和Web服务的Web应用程序是同一ASP.NET application
的一部分,则浏览器可以为每次调用Web服务无缝地发送表单身份验证票证(cookie)。
在配置文件中,您可以
<authorization>
<deny users="?" />
</authorization>
这将拒绝匿名用户访问,这也将涵盖Web服务。换句话说,除非用户登录并获得带有故障单的有效cookie,否则无法使用服务。当然,您必须HTTPS
。否则,中间的任何人都可以在标题中获取cookie并致电您的服务。
最后,在绝对意义上,无法确保没有人在您的应用程序之外调用Web服务。上述方法确保中间没有人调用您的服务。但是没有办法确保有效用户直接在您的应用程序之外调用服务,因为Web服务调用者是JavaScript,并且用户可以通过查看脚本或甚至查看脚本轻松找出您在JavaScript中构建的任何安全性。来自浏览器的流量。任何具有一定技术性的最终用户都可以重播请求或修改请求,并使用有效凭据提交给您的Web服务。
修改: - 强>
以下是您要启用FormsAuthentication的更多详细信息。
(1)在Web.config
<system.web>
下,确保您拥有此内容。
<authentication mode="Forms">
<forms loginUrl="Login.aspx" defaultUrl="~/" />
</authentication>
<authorization>
<deny users="?" />
</authorization>
这将确保所有未经过身份验证的(匿名)用户都被重定向到Login.aspx。
(2)使用您的登录逻辑实现Login.aspx
以获取用户ID和密码,并针对数据库或其他任何方式验证它们。一旦身份验证成功,即用户输入的ID和密码与您在数据库中的匹配,可以在登录按钮单击处理程序中,设置故障单。
protected void Button1_Click(object sender, EventArgs e)
{
// Do all your login logic here
// once user ID and password entered by the user are okay, call this
string ticket = FormsAuthentication.Encrypt(
new FormsAuthenticationTicket("userId", false, 15));
HttpCookie FormsCookie = new HttpCookie(
FormsAuthentication.FormsCookieName, ticket) { HttpOnly = true };
HttpContext.Current.Response.Cookies.Add(FormsCookie);
}
(3)将PrincipalPermissionAttribute
添加到这样的网络方法中。
public class Users : System.Web.Services.WebService
{
[PrincipalPermissionAttribute(SecurityAction.Demand)]
[WebMethod]
public List<User> GetUsers()
{
// Same code as what you have now
}
}
如果您现在转到任何页面,您将被重定向到login.aspx,您需要输入用户ID和密码并登录。登录时,将创建表单身份验证cookie并将其写入响应。从那时起,对您的应用程序的所有请求都将引入cookie(浏览器将为您执行此操作)。如果您没有登录,如果直接转到Web服务,您仍将被重定向到登录页面。正如我在原始答案中提到的,登录用户仍然可以直接访问Web服务。如果JavaScript可以做某事,用户也可以这样做。
BTW,Web服务(asmx)是一种弃用的技术。答案 1 :(得分:2)
这是一个非常重要的讨论话题。 有很多方法可以做到。
我们个人使用Service Stack for API,并在访问API时使用密钥。 密钥是一个guid,对于客户端和服务器保持不变。 如果客户端和服务器是相同的系统,则发布密钥不会有任何问题。
这里给出了非常详细的安全方法 http://www.stormpath.com/blog/secure-your-rest-api-right-way http://codebetter.com/johnvpetersen/2012/04/02/making-your-asp-net-web-apis-secure/
答案 2 :(得分:1)
您可以做的一件事是帮助阻止浏览器外部的调用,即在构建时在页面中放置一次性令牌,然后在AJAX调用期间发布。一个简单的实现是一个带有一堆随机值的数据库表(可能是32个字母数字或类似的)。构建页面时,从表中检索其中一个值并将其放入页面 - 当您创建AJAX表单时,请包含该值。
在服务器端,确保表中存在该值,然后将其从表中删除。
如果使用该值再次调用该服务,它将失败,因为该值不再在表中。
这意味着,为了生成有效的令牌,您必须首先获取该页面,然后您只能使用该令牌一次。
您可以在其中添加其他支票,例如IP地址,用户代理,Cookie值,到期日期等,并执行诸如使用密钥散列值或其他隐蔽安全方法之类的操作。
最后,正如Badri指出的那样,如果有人真的想通过简单地手动创建浏览器将为AJAX调用创建的HTTP请求,所有这些都可能被欺骗。您可以做的最好的事情是确保只有有效的用户才能调用该服务(无论他们使用的客户端技术如何),并且这是通过传统的表单身份验证来实现的。