代码之家  ›  专栏  ›  技术社区  ›  Eric Pohl

从非Web客户端调用ASP.NET 2.0身份验证服务

  •  3
  • Eric Pohl  · 技术社区  · 15 年前

    我正在开发一个.NET 2.0 WinForms应用程序,它调用一个ASP.NET 2.0网站。网站使用表单身份验证进行身份验证。在web.config中启用了身份验证服务,我已经做了一些 experiments 确认我可以通过JSON访问服务。

    我的问题是:在纯.NET环境(而不是ASP.NET)中,是否有任何内置代码可以使用System.Web.Extensions Web服务(AuthenticationService、ProfileService等)?我可以在客户端和服务器上的2.0环境中找到使用Silverlight和更高版本的WCF服务的示例,但不能找到任何内容。将身份验证服务添加为Web服务似乎是合乎逻辑的方法,但我无法让它指向我的开发服务器——我想这可能是一个单独的问题。

    如果我必须在较低的级别管理Ajax请求和响应,那么它肯定是可行的,但是如果已经有了这样的目的,那么它肯定会更容易,也不容易出错。

    2 回复  |  直到 14 年前
        1
  •  1
  •   Eric Pohl    14 年前

    我从来没有得到过答案,但最终在 this tutorial . 简短的回答是肯定的,我必须在相当低的水平上管理Ajax请求/响应。假设您有一个需要验证的用户名和密码,那么首先需要为其获取一个验证cookie。我用过 Json.NET library from Newtonsoft 对于JSON序列化和反序列化,您可以使用任何东西。

    Cookie GetFormAuthenticationCookie(string username, string password)
            {
                string uriString = ServerName + AUTH_SERVICE_URL;
                Uri uri = new Uri(uriString);
    
                // Need to cast this to HttpWebRequest to set CookieContainer property
                // With a null CookieContainer property on the request, we'd get an
                // empty HttpWebRequest.Cookies property
                HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
                request.Method = "POST";
                request.ContentType = "application/json; charset=utf-8";
                request.CookieContainer = new CookieContainer(); // needed to get non-empty Cookies collection back in response object
    
                // requestContents needs to look like this:
                // {
                //     username = 'theUserName',
                //     password = 'thePassword',
                //     createPersistentCookie = false
                // }
                string requestContents = GetJsonForLoginRequest(username, password);
    
                byte[] postData = Encoding.UTF8.GetBytes(requestContents);
                request.ContentLength = postData.Length;
                using (Stream dataStream = request.GetRequestStream())
                {
                    dataStream.Write(postData, 0, postData.Length);
                }
    
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                if (response.StatusCode != HttpStatusCode.OK)
                {
                    throw new WebException("Response returned HttpStatusCode " + response.StatusCode);
                }
    
                // For now, assuming response ContentType is "application/json; charset=utf-8"
                object responseJson;
                using (Stream responseStream = response.GetResponseStream())
                {
                    StreamReader reader = new StreamReader(responseStream);
                    string responseString = reader.ReadToEnd();
    
                    responseJson = JavaScriptConvert.DeserializeJson(responseString);
                }
    
                if (responseJson is bool)
                {
                    bool authenticated = (bool)responseJson;
                    if (authenticated)
                    {
                        // response was "true"; return the cookie
                        return response.Cookies[".ASPXFORMSAUTH"];
                    }
                    else
                    {
                        // apparently the login failed
                        return null;
                    }
                }
                else
                {
                    return null;
                }
            }
    

    接下来,将cookie添加到后续请求中。在我的例子中,这意味着将cookie添加到我使用的Web服务代理的cookieContainer中。

        2
  •  0
  •   Walter Stabosz    14 年前

    我无法使AuthenticationService工作。当我试图从我的winforms应用程序调用authentication_json_AppService.axd时,我一直收到404个错误。所以我最终编写了自己的JSON身份验证webmethod。

    抱歉,这不是C,我的项目是vb.net。我用过这个 http://progtutorials.tripod.com/Authen.htm 作为参考。

    <WebMethod(EnableSession:=True)>
    <ScriptMethod(ResponseFormat:=ResponseFormat.Json)>
    Public Function Login(ByVal username As String, ByVal password As String) As Boolean
    
        Dim result As Boolean = False
    
        ' If (FormsAuthentication.Authenticate(username,password)) ' this may also work to authenticate
        If (Membership.ValidateUser(username, password)) Then 
            FormsAuthentication.SetAuthCookie(username, False)
    
            Dim ticket As FormsAuthenticationTicket = New FormsAuthenticationTicket(username, False, 30)
            Dim ticketString As String = FormsAuthentication.Encrypt(ticket)
    
            Dim cookie As HttpCookie = New HttpCookie(FormsAuthentication.FormsCookieName, ticketString)
            Context.Response.Cookies.Add(cookie)
    
            result = True
    
        End If
    
        Return result
    
    End Function
    

    请确保您的web.config中的匿名用户可以访问您的身份验证Web服务。

      <location path="Authentication.asmx">
        <system.web>
          <authorization>
            <allow users="*" />
          </authorization>
        </system.web>
      </location>
    
    推荐文章