您的位置:首页 > 移动开发 > Android开发

Android与IIS身份验证——Form验证

2014-06-27 10:05 239 查看
内容摘要

  前言

  设计思路

  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 { get; set; }

/// <summary>

/// 是否执行成功

/// </summary>

public bool IsSuccess { get; set; }

/// <summary>

/// 登录账号

/// </summary>

public string Identity { get; set; }

/// <summary>

/// 执行结果

/// </summary>

public object Result { get; set; }

}

  接着,编写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

  代码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: