zoukankan      html  css  js  c++  java
  • Android与IIS身份验证——Form验证

    内容摘要

      前言

      设计思路 

      ASP.NET服务器端

      Android客户端

      运行结果

             

      上篇《Android与IIS身份验证——基本验证》实现了Android客户端与IIS的简单验证。而这种验证方式虽然使用起来比较简单,但是也有很多缺点。如,安全性较差,账号密码设置不灵活。让我们回顾一下ASP.NET的身份验证方式:Windows、Form和Passport。这三种验证方式中,Form身份验证方式最经常使用,因为它有很多优越性,其优点我就不一一介绍了。那么,怎样实现Android客户端与IIS的Form身份验证呢?我整理了一下,需要以下几个步骤:

       一、设计思路

       Android客户端访问IIS服务器时,当没有登陆时,ASP.NET通过Form集成验证方法会返回一个登陆页面。然后输入正确的用户名和密码,就可以进入主程序了。流程如图1.1所示。

    图1.1

      在Android客户端访问以IIS为宿主的ASP.NET服务器时,返回JSON格式来传递数据。客户端中,根据返回数据的不同而判断当前状态是否已登陆。由于Form验证是保存了Cookie,所示每次调用Http请求之前要先添加上次请求的Cookie。

      二、ASP.NET服务器端

      创建一个ASP.NET MVC网站项目。 

      首先,由于每次请求都返回JSON格式的数据,我们编写一个Model类来承载数据。

      

        public class ResponseResult
        {
            
    /// <summary>
            
    /// 是否已登录
            
    /// </summary>
            public bool IsAuthenticated { getset; }

            
    /// <summary>
            
    /// 是否执行成功
            
    /// </summary>
            public bool IsSuccess { getset; }

            
    /// <summary>
            
    /// 登录账号
            
    /// </summary>
            public string Identity { getset; }

            
    /// <summary>
            
    /// 执行结果
            
    /// </summary>
            public object Result { getset; }
        }

      接着,编写HomeController:

      

        [HandleError]
        
    public class HomeController : Controller
        {
            [Authorize]
            
    public ActionResult Index()
            {
                
    return Json(new ResponseResult
                {
                    Result 
    = "登陆成功",
                    IsAuthenticated 
    = true,
                    IsSuccess 
    = true,
                    Identity 
    = this.User.Identity.Name
                }, 
    "text/html", JsonRequestBehavior.AllowGet);
            }

            
    public ActionResult LogOn()
            {
                
    return Json(new ResponseResult
                {
                    Result 
    = "您尚未登录",
                    IsSuccess 
    = true
                }, 
    "text/html", JsonRequestBehavior.AllowGet);
            }

            
    public ActionResult Register(string account, string password)
            {
                
    if (account == "liudong" && password == "123")
                {
                    FormsAuthentication.SetAuthCookie(account, 
    false);
                    
    return Json(new ResponseResult
                    {
                        Result 
    = "登录成功",
                        IsSuccess 
    = true,
                        IsAuthenticated 
    = true,
                        Identity 
    = account
                    }, 
    "text/html", JsonRequestBehavior.AllowGet);
                }
                
    else
                {
                    
    return Json(new ResponseResult
                    {
                        Result 
    = "用户名或密码错误",
                    }, 
    "text/html", JsonRequestBehavior.AllowGet);
                }
            }

      Index Action为登陆认证后才能访问的Action。

      LogOn Action为未登陆时跳转的Action。

      Register Action为登陆Action,用户名和密码正确后就保存Form验证的Cookie。

      然后,在Web.config中配置Form验证配置

    <authentication mode="Forms">
          
    <forms loginUrl="~/Home/LogOn" timeout="2880" />
    </authentication>


      最后,配置IIS,部署ASP.NET MV网站,如图2.1所示。

     图2.1

      三、Android客户端

       首先,编写一个调用Http请求的类。

      

    package ld.com.authorize;

    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.List;

    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.NameValuePair;

    import org.apache.http.client.CookieStore;
    import org.apache.http.client.entity.UrlEncodedFormEntity;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.impl.client.AbstractHttpClient;
    import org.apache.http.impl.client.DefaultHttpClient;

    import android.util.Log;

    public abstract class HttpHelper {

        
    private final static String TAG = "HttpHelper";
        
    private final static String SERVER_URL = "http://192.168.1.104:180/Home/";

        
    private static CookieStore cookieStore;

        
    public static String invoke(String actionName, List<NameValuePair> params) {
            String result 
    = null;
            
    try {
                String url 
    = SERVER_URL + actionName + "/";
                Log.d(TAG, 
    "url is" + url);

                HttpPost httpPost 
    = new HttpPost(url);
                
    if (params != null && params.size() > 0) {
                    HttpEntity entity 
    = new UrlEncodedFormEntity(params, "UTF-8");
                    httpPost.setEntity(entity);
                }

                DefaultHttpClient httpClient 
    = new DefaultHttpClient();

                
    // 添加Cookie
                if (cookieStore != null) {
                    httpClient.setCookieStore(cookieStore);
                }

                HttpResponse httpResponse 
    = httpClient.execute(httpPost);

                StringBuilder builder 
    = new StringBuilder();
                BufferedReader reader 
    = new BufferedReader(new InputStreamReader(
                        httpResponse.getEntity().getContent()));
                
    for (String s = reader.readLine(); s != null; s = reader.readLine()) {
                    builder.append(s);
                }
                result 
    = builder.toString();
                Log.d(TAG, 
    "result is ( " + result + " )");

                
    // 保存Cookie
                cookieStore = ((AbstractHttpClient) httpClient).getCookieStore();
            } 
    catch (Exception e) {
                Log.e(TAG, e.toString());
            }
            Log.d(TAG, 
    "over");
            
    return result;
        }

        
    public static String invoke(String actionName) {
            
    return invoke(actionName, null);
        }
    }

        注意的是,需要存储一个全局的Cookie,在每次调用前添加上去,再在调用j结束后保存它。

      接着,添加两个布局文件:

      

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation
    ="vertical" android:layout_width="fill_parent"
        android:layout_height
    ="fill_parent">


        
    <TextView android:text="账号" android:layout_width="fill_parent"
            android:layout_height
    ="20dip" />

        
    <EditText android:layout_width="fill_parent" android:hint="请输入账号"
            android:layout_height
    ="40dip" android:id="@+id/edtAccount" />

        
    <TextView android:text="密码" android:layout_width="fill_parent"
            android:layout_height
    ="20dip" />

        
    <EditText android:layout_width="fill_parent" android:hint="请输入密码"
            android:password
    ="true" android:layout_height="40dip" android:id="@+id/edtPassword" />

        
    <Button android:text="登录" android:layout_width="fill_parent"
            android:layout_height
    ="40dip" android:id="@+id/btnLogon" />
    </LinearLayout>
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation
    ="vertical" android:layout_width="fill_parent"
        android:layout_height
    ="fill_parent">

        
    <Button android:text="调用" android:id="@+id/btnInvoke"
            android:layout_width
    ="fill_parent" android:layout_height="wrap_content" />

    </LinearLayout>

       然后、编写登陆和主Activity

    package ld.com.authorize;

    import java.util.ArrayList;
    import java.util.List;

    import org.apache.http.NameValuePair;
    import org.apache.http.message.BasicNameValuePair;
    import org.json.JSONException;
    import org.json.JSONObject;

    import android.app.Activity;
    import android.app.ProgressDialog;
    import android.content.Intent;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.Toast;

    public class LogonActivity extends Activity {

        
    private final String TAG = this.getClass().getSimpleName();

        
    private EditText edtAccount;
        
    private EditText edtPassword;

        
    private Button btnLogon;

        
    /** Called when the activity is first created. */
        @Override
        
    public void onCreate(Bundle savedInstanceState) {
            
    super.onCreate(savedInstanceState);
            setContentView(R.layout.logon);

            edtAccount 
    = (EditText) this.findViewById(R.id.edtAccount);
            edtPassword 
    = (EditText) this.findViewById(R.id.edtPassword);

            btnLogon 
    = (Button) this.findViewById(R.id.btnLogon);

            setButtonOnClick();
        }

        
    private void setButtonOnClick() {
            
    this.btnLogon.setOnClickListener(new OnClickListener() {

                @Override
                
    public void onClick(View v) {
                    
    // TODO Auto-generated method stub
                    AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {

                        
    private ProgressDialog progressDialog;

                        @Override
                        
    protected void onPostExecute(String result) {
                            
    // TODO Auto-generated method stub
                            
    // super.onPostExecute(result);
                            progressDialog.cancel();
                            Log.d(TAG, result);
                            
    try {
                                JSONObject json 
    = new JSONObject(result);
                                String msg 
    = json.getString("Result");
                                
    // 是否登录
                                if (json.getBoolean("IsSuccess")) {
                                    Toast.makeText(LogonActivity.
    this, msg,
                                            Toast.LENGTH_SHORT).show();

                                    
    // 跳转登录Activity
                                    Intent intent = new Intent();
                                    intent.setClass(LogonActivity.
    this,
                                            MainActivity.
    class);
                                    LogonActivity.
    this.startActivity(intent);
                                } 
    else {
                                    Toast.makeText(LogonActivity.
    this, msg,
                                            Toast.LENGTH_SHORT).show();
                                }
                            } 
    catch (JSONException e) {
                                
    // TODO Auto-generated catch block
                                Log.e(TAG, e.toString());
                            }
                        }

                        @Override
                        
    protected void onPreExecute() {
                            
    // TODO Auto-generated method stub
                            super.onPreExecute();
                            progressDialog 
    = new ProgressDialog(LogonActivity.this);
                            progressDialog.setCancelable(
    false);
                            progressDialog
                                    .setProgressStyle(ProgressDialog.STYLE_SPINNER);
                            progressDialog.setTitle(
    "登录中,请稍后...");
                            progressDialog.show();
                        }

                        @Override
                        
    protected String doInBackground(Void... arg0) {
                            
    // TODO Auto-generated method stub
                            String account = edtAccount.getText().toString();
                            String password 
    = edtPassword.getText().toString();
                            List
    <NameValuePair> params = new ArrayList<NameValuePair>();
                            params.add(
    new BasicNameValuePair("account", account));
                            params.add(
    new BasicNameValuePair("password", password));

                            
    try {
                                
    return HttpHelper.invoke("Register", params);
                            } 
    catch (Exception e) {
                                Log.e(TAG, e.toString());
                                
    return null;
                            }
                        }
                    };
                    task.execute();
                }
            });
        }
    }
    package ld.com.authorize;

    import org.json.JSONException;
    import org.json.JSONObject;

    import android.app.Activity;
    import android.app.ProgressDialog;
    import android.content.Intent;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.Toast;

    public class MainActivity extends Activity {

        
    private final String TAG = this.getClass().getSimpleName();

        
    private Button btnInvoke;

        
    /** Called when the activity is first created. */
        @Override
        
    public void onCreate(Bundle savedInstanceState) {
            
    super.onCreate(savedInstanceState);
            setContentView(R.layout.main);

            btnInvoke 
    = (Button) this.findViewById(R.id.btnInvoke);

            setInvokeOnClick();
        }

        
    private void setInvokeOnClick() {
            btnInvoke.setOnClickListener(
    new OnClickListener() {

                @Override
                
    public void onClick(View v) {
                    
    // TODO Auto-generated method stub
                    AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {

                        
    private ProgressDialog progressDialog;

                        @Override
                        
    protected void onPostExecute(String result) {
                            
    // TODO Auto-generated method stub
                            
    // super.onPostExecute(result);
                            progressDialog.cancel();
                            Log.d(TAG, result);
                            
    try {
                                JSONObject json 
    = new JSONObject(result);
                                
    // 是否登录
                                if (json.getBoolean("IsAuthenticated")) {
                                    String msg 
    = json.getString("Identity"+ ":"
                                            
    + json.getString("Result");
                                    Toast.makeText(MainActivity.
    this, msg,
                                            Toast.LENGTH_SHORT).show();
                                } 
    else {
                                    Toast.makeText(MainActivity.
    this,
                                            json.getString(
    "Result"),
                                            Toast.LENGTH_SHORT).show();

                                    
    // 跳转登录Activity
                                    Intent intent = new Intent();
                                    intent.setClass(MainActivity.
    this,
                                            LogonActivity.
    class);                                
                                    MainActivity.
    this.startActivity(intent);
                                }
                            } 
    catch (JSONException e) {
                                
    // TODO Auto-generated catch block
                                Log.e(TAG, e.toString());
                            }
                        }

                        @Override
                        
    protected void onPreExecute() {
                            
    // TODO Auto-generated method stub
                            super.onPreExecute();
                            progressDialog 
    = new ProgressDialog(MainActivity.this);
                            progressDialog.setCancelable(
    false);
                            progressDialog
                                    .setProgressStyle(ProgressDialog.STYLE_SPINNER);
                            progressDialog.setTitle(
    "调用中,请稍后...");
                            progressDialog.show();
                        }

                        @Override
                        
    protected String doInBackground(Void... arg0) {
                            
    // TODO Auto-generated method stub
                            try {
                                
    return HttpHelper.invoke("Index");
                            } 
    catch (Exception e) {
                                Log.e(TAG, e.toString());
                                
    return null;
                            }
                        }

                    };
                    task.execute();
                }
            });
        }
    }

      最后,设置访问权限:<uses-permission android:name="android.permission.INTERNET" />

      

      四、运行结果

      1.进入主MainActivity,图4.1.1所示。

    图4.1.1

      2.调用Http请求,图4.2.1所示。

    图4.2.1

      3.由于没有登陆,所以跳转到登陆Activity,图4.3.1所示。

    图4.3.1

      4.故意输入错误密码使其登陆失败,图4.4.1所示。

    图4.4.1

      5.输入正确的密码后跳转到主Activity,如图4.5.1所示。

    图4.5.1

      6.再一次调用Http请求,这次是已登陆状态,图4.6.1所示。

    图4.6.1

      代码下载

      作者:刘冬.NET

      出处:http://www.cnblogs.com/GoodHelper/archive/2011/08/19/android_iis_02.html

      欢迎转载,但须保留版权。

  • 相关阅读:
    angularIO 路由守卫
    vue-property-decorator用法
    windows mysql 忘记密码
    OSPF 做负载均衡
    NLB 部署网络负载平衡
    flexible.js 布局详解
    python setup.py 构建
    python Zope.interface安装使用
    lnmp菜单
    linux下的文件删除原理
  • 原文地址:https://www.cnblogs.com/GoodHelper/p/android_iis_02.html
Copyright © 2011-2022 走看看