WebService Login Verification Four Ways

Source: Internet
Author: User
Tags urlencode

In this Web API-infested era, the Web service technology is actually a bit outdated, outdated technology does not mean that there is no use, and some places can still continue with his, I explained the Web service, from my recent interview was asked the relevant questions, I just re-review and summarize here, to the novice to point to the road, Daniel can ignore it, of course, the shortcomings of the Please advise, thank you!

Web service authentication, there are many related articles on the Internet, summed up there are: based on custom SoapHeader authentication, form validation, Integrated Windows authentication, service methods to add one or several validation parameters ; no nonsense. Directly share the implementation of the Code bar, in the middle of the area involved in the attention, I will have explanatory text.

1. Based on custom SoapHeader validation

Define Service: (Note that Uservalidationsoapheader must have a parameterless constructor, otherwise it cannot be serialized)

Uservalidationsoapheader:public class Uservalidationsoapheader:soapheader {public string UserName {get ; Set        public string Password {get; set;} Public Uservalidationsoapheader () {} public bool IsValid () {if (string. IsNullOrEmpty (UserName) | | String. IsNullOrEmpty (Password)) {throw new Exception ("username and password cannot be empty!            "); } if (!string. Equals (UserName, "admin") | | !string. Equals (Password, "123456")) {throw new Exception ("Username or password is incorrect!            ");        } return true; }}//soapheaderwebservice: [WebService (Namespace = "http://www.zuowenjun.cn")] [webservicebinding (ConformsTo = Ws Iprofiles.basicprofile1_1)] [System.ComponentModel.ToolboxItem (false)]//To allow the use of ASP. NET AJAX to invoke this Web service from the script, cancel the    Comments.        [System.Web.Script.Services.ScriptService] public class SoapHeaderWebService:System.Web.Services.WebService { Public Uservalidationsoapheader uservalidation;        [WebMethod (description= "greetings")] [SoapHeader ("Uservalidation")] public string Helloto (string name) {if (Uservalidation.isvalid () &&!string.            IsNullOrEmpty (name)) {return "Hello" + name;        } return "Hello world!"; }    }

The client first refers to the service through the service address, and there are two types of service references, which are divided into service references and Web service references (the service references are not restated later)

Service Reference: (This is the generation of the Web service proxy class in WCF mode)

Web Service Reference:

(If you right-click on the project, you can tap "Add Web Reference" to this screen)

The client uses the following:

        private void Callwebservicefromwebreference () {try {var svc = new Re                Fwebsoapheaderwebservice.soapheaderwebservice (); Svc. Uservalidationsoapheadervalue = new Refwebsoapheaderwebservice.uservalidationsoapheader () {UserName = "admin",                Password = "123456"}; string result = Svc.                Helloto (TextBox1.Text);            Label1.Text = result; } catch (Exception ex) {Label1.Text = ex.            Message; }} private void Callwebservicefromservicereference () {try {VA                R svc = new Refsoapheaderwebservice.soapheaderwebservicesoapclient ();                var header = new Refsoapheaderwebservice.uservalidationsoapheader (); Header.                UserName = "admin"; Header.                Password = "123456"; string result = Svc.                Helloto (header, TextBox1.Text);     Label1.Text = result;       } catch (Exception ex) {Label1.Text = ex.            Message; }} protected void button1_click (object sender, EventArgs e) {if (radiobuttonlist1.select            Edvalue = = "1") {callwebservicefromservicereference ();            } else {callwebservicefromwebreference (); }        }

The above code I for two kinds of Web service reference made a different use instance, the key to see the method call, service reference generated under the service method parameter will automatically add a SoapHeader parameter, and the Web service reference is not, I feel that the use of Web services reference based on this validation is more convenient, You can call different service methods multiple times because you only need to assign the SoapHeader instance one time.

2.Form Verification

Define the service:

Web Service dedicated to login: [WebService (Namespace = "http://www.zuowenjun.cn")] [webservicebinding (ConformsTo = Wsiprofiles.basi    Cprofile1_1)] [System.ComponentModel.ToolboxItem (false)]//To allow the use of ASP. NET AJAX to invoke this Web service from the script, uncomment the downstream.        [System.Web.Script.Services.ScriptService] public class FormAuthWebService:System.Web.Services.WebService { [WebMethod] public bool Login (string Username, string password) {return Userbusiness.login (user        name, password); }}//Normal Web service: [WebService (Namespace = "http://www.zuowenjun.cn")] [webservicebinding (ConformsTo = wsiprofiles.ba    Sicprofile1_1)] [System.ComponentModel.ToolboxItem (false)]//To allow the use of ASP. NET AJAX to invoke this Web service from the script, uncomment the downstream.        [System.Web.Script.Services.ScriptService] public class FormAuthHelloWebService:System.Web.Services.WebService { [WebMethod] public string Helloto (string name) {if (!string.         IsNullOrEmpty (name)) {       Return "Hello" + name;        } return "Hello World";        } [WebMethod] public void Logout () {userbusiness.logout ();        }}//Business Helper class: public static class Userbusiness {public static bool Login (string userName, string password) {if (string. IsNullOrEmpty (userName) | | String. IsNullOrEmpty (password)) {throw new Exception ("username and password cannot be empty!            "); } if (!string. Equals (UserName, "admin") | | !string. Equals (password, "123456")) {throw new Exception ("Username or password is incorrect!            ");            } saveloginstauts (UserName);        return true;        } public static bool IsAuthenticated () {return HttpContext.Current.Request.IsAuthenticated;        } public static void Logout () {System.Web.Security.FormsAuthentication.SignOut (); } private static void Saveloginstauts (string useRname) {System.Web.Security.FormsAuthentication.SetAuthCookie (UserName, false); }    }

As can be seen from the above code, this is based on ASP. NET form verification to save the login state, the other code is the same as normal

Because ASP. NET form validation is used, Web. config needs to include the following configuration:

Add the following configuration to the System.Web node because I have placed the Web service in the Services directory only to restrict the directory    <authentication mode= "Forms" >      < Forms Name= "Auth.webservice" loginurl= "~/services/formauthwebservice.asmx/login" >      </forms>    < /authentication>    <webServices>      <protocols>        <add name= "HttpSoap"/>        <add Name= "HttpPost"/>        <add name= "HttpGet"/> <add        name= "Documentation"/>      </protocols >    </webServices>  </system.web>  <location path= "Services" >    < system.web>      <authorization>        <deny users= "?" />      </authorization>    </system.web>  </location>

Note the following 2 points:

1. Above loginurl= "~/services/formauthwebservice.asmx/login", here I directly will not login directly to login, because if you do not add login, Then you will not be able to debug the login and other service methods on the Web browser.

2. Because of the use of form verification, and prohibit anonymous access, resulting in the inability to properly reference the service, because the service reference is also an HTTP request, the default is not logged in the case, you refer to the limited service address, it will automatically jump to the login service address, so in response to this problem, I used two ways, The first is: Do not prohibit anonymous access, when the service reference succeeds, plus the configuration, the second is: do not directly reference the service, using the Code dynamic Request service method to make related calls, the client uses the code as follows:

First: Using a service reference: protected void button2_click (object sender, EventArgs e) {try {                Cookiecontainer Cookiecontainer = new Cookiecontainer ();                var svc = new Refformauthloginwebservice.formauthwebservice (); Svc. Cookiecontainer = Cookiecontainer; Shared Cookie Container if (SVC. Login ("admin", "123456")) {var svc2 = new Refformauthwebservice.formauthhellowebservice                    (); SVC2. Cookiecontainer = cookiecontainer;//Shared cookie Container Label2.Text = svc2.                Helloto (TextBox2.Text); }} catch (Exception ex) {label2.text = ex.            Message;            }}//The second type: Call with dynamic request: protected void button2_click (object sender, EventArgs e) {try                {Cookiecontainer Cookiecontainer = new Cookiecontainer (); var result = Callwebservicefromhttpwebrequest("Formauthwebservice.asmx/login", "username=admin&password=123456", Cookiecontainer); Label2.Text = result. selectSingleNode ("//ns:boolean", Getxmlnamespacemanager (Result). NameTable)).                InnerText; var result2 = callwebservicefromhttpwebrequest ("Formauthhellowebservice.asmx/helloto", "name=" +                Httputility.urlencode (TextBox2.Text, Encoding.UTF8), Cookiecontainer); Label2.Text = result2. selectSingleNode ("//ns:string", Getxmlnamespacemanager (result2. NameTable)).            InnerText; catch (Exception ex) {label2.text = ex.            Message; }

The

Helper methods are defined as follows:

        Private XmlDocument callwebservicefromhttpwebrequest (string serviceurl,string serviceparams,cookiecontainer cookie  Container) {HttpWebRequest request = (HttpWebRequest) webrequest.create ("http://localhost:8768/Services/"            + serviceurl); Request.            Method = "POST"; Request.            ContentType = "application/x-www-form-urlencoded"; Request.            Credentials = CredentialCache.DefaultCredentials; byte[] data = Encoding.UTF8.GetBytes (serviceparams);//Parameter request. ContentLength = data.            Length; Request. Cookiecontainer = Cookiecontainer; Shared Cookie Container Stream writer = Request.            GetRequestStream (); Writer. Write (data, 0, data.            Length); Writer.            Close (); WebResponse response = Request.            GetResponse (); StreamReader sr = new StreamReader (response.            GetResponseStream (), Encoding.UTF8); String Retxml =SR.            ReadToEnd (); Sr.            Close (); XmlDocument doc = new xmldocUment (); Doc.            LOADXML (Retxml);        return doc; } private XmlNamespaceManager Getxmlnamespacemanager (XmlNameTable table) {XmlNamespaceManager NS            MGR = new XmlNamespaceManager (table);            Nsmgr.addnamespace ("ns", "http://www.zuowenjun.cn");        return nsmgr; }

Here is a description, whether using a service reference or dynamic invocation of the service, you need to ensure that the same cookie container is referenced, and in the dynamic invocation of the service, it is also important to note that the final return of the result is XML, need to be resolved to get the specified value, related considerations, see this article, "C # Operation XML Selectnodes,selectsinglenode always return null and XPath introduction, in fact, after looking at the XML namespace to know the problem, you can also remove the namespace, so that the resolution is more convenient, the following code:

Here is the method of getting the XML called to remove the namespace: String Retxml = Removenamespace (sr. ReadToEnd ());p rivate string removenamespace (string xml)        {            var reg = new System.Text.RegularExpressions.Regex ( "Xmlns=\". *\ "", System.Text.RegularExpressions.RegexOptions.IgnoreCase);            Return Reg. Replace (XML, "");        } protected void button2_click (object sender, EventArgs e) {...                var result = Callwebservicefromhttpwebrequest ("Formauthwebservice.asmx/login", "username=admin&password=123456 ", Cookiecontainer);                Label2.Text = result. selectSingleNode ("//boolean"). InnerText;                var result2 = callwebservicefromhttpwebrequest ("Formauthhellowebservice.asmx/helloto", "name=" + Httputility.urlencode (TextBox2.Text, Encoding.UTF8), cookiecontainer);                Label2.Text = result2. selectSingleNode ("//string"). InnerText, ...}

3. Integrated Windows authentication, this is simple, first set IIS to Integrated Windows authentication, service definition no special code

The client uses the following:

Test.WebReference.Service1 service= new Test.WebReference.Service1 (); Generates a Web service instance   service. Credentials = new NetworkCredential ("User", "123456"); User is the username, and the user needs to have certain permissions   Lbltest.text =service. Helloto ("Zuowenjun"); Calling the Web service method  

Web page Sample code:

    <form id= "Form1" runat= "Server" > <fieldset> <legend> Invoke service based on custom SoapHeader authentication </legend> & lt;div> <asp:radiobuttonlist id= "RadioButtonList1" runat= "server" repeatdirection= "Horizontal" > &lt ; Asp:listitem value= "1" >from Service reference</asp:listitem> <asp:listitem value= "2" >From Web Refer ence</asp:listitem> </asp:RadioButtonList> <asp:textbox id= "TextBox1" runat= "Server" ></ asp:textbox> <asp:button id= "Button1" runat= "Server" text= "button" onclick= "Button1_Click"/> <b R/> <asp:label id= "Label1" runat= "Server" text= "Label" ></asp:Label> </div> </fieldse t> <p>  </p> <p>  </p> <p>  </p> & Lt;fieldset> <legend> Invoke service </legend> <div> <asp:textbox id= "TextBox2" Run based on custom form authentication at= "Server" ></asp:textbox> <asp:button id= "Button2" runat= "Server" onclick= "button2_click" text= "button"/> <br/&        Gt <asp:label id= "Label2" runat= "Server" text= "Label" ></asp:Label> </div> </fieldset> &LT;P&G        T  </p> <p>  </p> <p>  </p> <fieldset> <leg End> Call service </legend> <div> <asp:textbox id= "TextBox3" runat= "Server" ></asp:t based on custom Windows authentication        extbox> <asp:button id= "Button3" runat= "Server" text= "button" onclick= "Button3_Click"/> <br/> <asp:label id= "Label3" runat= "Server" text= "Label" ></asp:Label> </div> < /fieldset> </form>

The final results are as follows:


Due to work hours written, so some haste, deficiencies, please point out, thank you! ~v~

Complementary points of knowledge:

I above the code in verifying the user login, if the validation does not pass, I am directly thrown a exception,web service before returning to the client will be wrapped as a soapexception type of exception, so that the client can not be very direct view of the error content, so this article may be used here "Encapsulation SoapException Handling WebService Exception" method to add the method of formatting SoapException and parsing SoapException method.

For a way to share cookies when web Serivce are used in multiple ASP. NET pages, the implementation code is as follows:

The Web service is first referred to as normal, and then the custom inherits the service class from the reference, instantiates the Cookiecontainer in its constructor, and saves it to a static field;

Instead of invoking the referenced service, you should call these custom subclasses to implement a shared cookie

    public class FormAuthHelloWebServiceEx:RefFormAuthWebService.FormAuthHelloWebService {private static Cook        Iecontainer Cookiecontainer;        Static Formauthhellowebserviceex () {cookiecontainer = new System.Net.CookieContainer ();            } public Formauthhellowebserviceex (Cookiecontainer ckcontainer) {if (Cookiecontainer! = null)            {Cookiecontainer = Ckcontainer; } this.        Cookiecontainer = Cookiecontainer; }} public class FormAuthWebServiceEx:RefFormAuthLoginWebService.FormAuthWebService {private static Coo        Kiecontainer Cookiecontainer;        Static Formauthwebserviceex () {cookiecontainer = new System.Net.CookieContainer ();            } public Formauthwebserviceex (Cookiecontainer ckcontainer) {if (Cookiecontainer! = null)            {Cookiecontainer = Ckcontainer; } this. CookiecOntainer = Cookiecontainer; }    }

WebService Login Verification Four ways

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.