Asp.net Webservice - 使用jquery AJAX安全地调用webservice

时间:2013-07-07 11:44:15

标签: jquery asp.net ajax web-services

我想在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>

3 个答案:

答案 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/

另外举一个例子 Building Secure Public API with PHP/MYSQL

答案 2 :(得分:1)

您可以做的一件事是帮助阻止浏览器外部的调用,即在构建时在页面中放置一次性令牌,然后在AJAX调用期间发布。一个简单的实现是一个带有一堆随机值的数据库表(可能是32个字母数字或类似的)。构建页面时,从表中检索其中一个值并将其放入页面 - 当您创建AJAX表单时,请包含该值。

在服务器端,确保表中存在该值,然后将其从表中删除。

如果使用该值再次调用该服务,它将失败,因为该值不再在表中。

这意味着,为了生成有效的令牌,您必须首先获取该页面,然后您只能使用该令牌一次。

您可以在其中添加其他支票,例如IP地址,用户代理,Cookie值,到期日期等,并执行诸如使用密钥散列值或其他隐蔽安全方法之类的操作。

最后,正如Badri指出的那样,如果有人真的想通过简单地手动创建浏览器将为AJAX调用创建的HTTP请求,所有这些都可能被欺骗。您可以做的最好的事情是确保只有有效的用户才能调用该服务(无论他们使用的客户端技术如何),并且这是通过传统的表单身份验证来实现的。