2013-07-10

Android跨平台應用(一) - 運用AD登入

人永遠是不會滿足的,而且老闆更不容易滿足,這是真的!QQ"

老闆不滿足,他也不會讓你滿足(薪水),所以當一個稱職的員工,就要盡力滿足他

好了,廢話說完了,再來進入正題.....

當Android原生寫到一定程度時通常都會想還有什麼可以應用

跨平台應用是會被用到也很常會被使用到的,所以就來往這方式研究

這次來研究如果運用在公司內很常見的AD來登入自己開發的Android應用程式

AD是什麼?AD(Active Directory)說明在這裡

也可以在左邊用Active Directory進維基百科查詢,這裡就不再說明

這樣的目的當然是為了SSO(Single-Sign-On單一登入),不用重覆建立登入資料

看起來好像很方便,實際上.........也是很方便,哈!而且如果不這樣做,老闆是不會滿足的xd

先來說一下原理好了:




佈局:

1.Android應用程式放在Android手機內(廢話..)

2.Web Service放在可對外的Server主機內

3.AD Server放在公司內部Server主機內


說明:

我的設計是手機端經由Web Service傳送帳號密碼給AD Server進行驗證

其實也是可以直接傳給AD Server進行驗證,但為什麼要這樣設計呢?

因為兩個原因:1.可以加密確保帳密的安全
                            2.AD Server IP位置改變時不用重新修改Android應用程式,使用者還要更新
                               只需修改Web Service對應的AD Server 的IP位置即可

光原因二就有必要用這種設計方式了,因為AD Server IP改變後如果使用者沒有更新新的apk檔,基本上這個程式就會出錯,所以中間加一個Web Service彈性是比較高的

再來看一下程式碼:

Web Service
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Data.OleDb;
using System.Collections;
using System.Data;
using System.DirectoryServices;

/// <summary>
/// Search 的摘要描述
/// </summary>
[WebService(Namespace = "http://WebServiceForApp/")]//必須和android手機內的Namespace對應
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// 若要允許使用 ASP.NET AJAX 從指令碼呼叫此 Web 服務,請取消註解下一行。
// [System.Web.Script.Services.ScriptService]
public class Search : System.Web.Services.WebService {
    string _path;
    string _filterAttribute;

    public OleDbConnection Conn = new OleDbConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);

    public Search () {

        //如果使用設計的元件,請取消註解下行程式碼 
        //InitializeComponent(); 
    }

    [WebMethod]
    public bool Verification(string username,string pwd)
    {
        string domain = "192.168.2.211";//AD Server IP位置
        bool V = true;
        _path = "LDAP://" + domain;
        string domainAndUsername = domain + @"\" + username;
        DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd);

        try
        {
            //Bind to the native AdsObject to force authentication.            
            object obj = entry.NativeObject;
            DirectorySearcher search = new DirectorySearcher(entry);

            search.Filter = "(SAMAccountName=" + username + ")";
            search.PropertiesToLoad.Add("cn");
            SearchResult result = search.FindOne();

            //帳號是:it01
            //回覆驗證資料,無為null
            //有Data內容會是這個樣子:LDAP://192.168.2.211/CN=it01,OU=資訊部,OU=管理處,DC=goldjoint,DC=com
            if ((result == null))
            {
                V = false;
            }

            //Update the new path to the user in the directory.
            _path = result.Path;
            _filterAttribute = (string)result.Properties["cn"][0];

        }
        catch (Exception ex)
        {
            //throw new Exception("Error authenticating user. " + ex.Message);
            V = false;
        }


        return V;
    }
}


注意:
手機端我是有使用到ksoap2
所以必須先掛載ksoap2的jar檔進來,以便連結Web Service
網路上掛載的方法很多都有寫,所以這裡就不再重覆,請先掛載。



Android手機端
void WebData()
{
//從網路上獲取資料
String NAMESPACE = "http://WebServiceForApp/";//必須和Web Service內的Namespace對應
String URL = "http://你的WebService位置/AppWebService/Search.asmx";
String SOAP_ACTION = "http://WebServiceForApp/Verification";//NAMESPACE+WebService METHOD_NAME
String METHOD_NAME = "Verification";  

//Data
SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME); 
PropertyInfo sayHelloPI = new PropertyInfo();
sayHelloPI.setName("username");//加入帳號
sayHelloPI.setValue(id);
sayHelloPI.setType(String.class);
Request.addProperty(sayHelloPI);

PropertyInfo sayHelloPI2 = new PropertyInfo();
sayHelloPI2.setName("pwd");//加入密碼
sayHelloPI2.setValue(pw);
sayHelloPI2.setType(String.class);
Request.addProperty(sayHelloPI2);

//Request.addProperty("ID",strSearch);
SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
soapEnvelope.dotNet=true;
soapEnvelope.setOutputSoapObject(Request);
HttpTransportSE aht=new HttpTransportSE(URL);
//aht.debug=true;
try {
aht.call(SOAP_ACTION, soapEnvelope);
//SoapObject result = (SoapObject)soapEnvelope.getResponse();
SoapPrimitive result = (SoapPrimitive)soapEnvelope.getResponse();//單純Data用這個

//存入回傳資料(String Check存入True or False)
check = result.toString();//Check就能拿來檢查是否有AD驗證過了


} catch (SoapFault e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}	
}

說明:

有幾個重點要注意:
1.Namespace對應,Web Service和Android手機端的Namespace一定要相同
2.我是有另外專為這個Web Service在IIS上新增一個網站做控管(這點好像不是什麼重點xd)
3.加不加密看狀況,我是走一般網路的80 port,也能走其他的port,但要另外開放和設定
   應用程式封裝成apk檔有一定的安全性了,因為Android 2.3.3以後的版本Google有加入亂碼
   ,程式碼會重排,所以要知道的人還是會知道(應該是自己人xd),如果還是要小心一點可以
   加密,反正可以在Web Service解密就好,這樣就能再送AD Server驗證,本人完全沒加密xd

以上程式碼是可以RUN的,而且也在RUN中,所以如果你不能RUN請留言我幫您看一下為什麼不能RUN。
 
我只取出部份的程式碼,其他部份可能要自己拼湊,不要跟我要全部的程式碼,因為那不是我的,所以我不能給你。


沒有留言:

張貼留言

您的寶貴建議是我前進的動力!