縣市端新增syncdata spi功能

URL Link //n.sfs.tw/13432

2019-08-08 20:35:01 By jung

為了因應即將上線的新建帳號平臺,需要配合MERGE縣市端程式以及撰寫accountdatasource的SPI函式庫

新的管理介面多出可勾選OIDC或OAUTH流程

為了要讓部裡主機可以透過OAUTH2流程,呼叫縣市已建置的同步反查用的SYNCDATA API,所以,oauth的flow要改成client_credentials

除了帳號管理平臺之外,原本的教育部認證主機也要改成支援client_credentials

先git pull /authserver/cncaccountdatasource/master主程式

再到git 建立 /authserver/cncaccountdatasource縣市的分支後,修改程式以對應各縣市syncdata回傳的資料型態(如以縣市帳號或GUID反查)

cncaccountdatasource這個程式它會利用httpclient走oauth2的流程,先取TOKEN再問SYNCDATA的API

縣市端開給部裡主機(帳號管理以及OIDC)會去讀資料庫中存的clientid和clientsecret

以上是概念,以下紀錄實作步驟

 

一、先更新縣市端認證程式的函式庫:cnclibs 1.0.12, EduDataType 1.0.5.6

我測試過,雖然CncResource專案的POM是1.0.11但似乎有狀況,編譯時會去找edudatatype 1.0.5.4找不到就出錯了

所以我試出來的方法就是先更新POM到cnclibs 1.0.12, EduDataType 1.0.5.6 確定這二個dependency都有下載完成了再做MERGE 的動作

 

二、 pull latest tc-idp-wicket8 codes and merge into current branch

再來拉回最新的程式後,進行合併到自己縣市的分支程式

cncauthserver: tc-idp-wicket8

CncResource: tc_resource_wicket8

這二個專案都必須進行函式庫更新及合併分支的動作

如果函式庫都正常加入了,那麼cncauthserver及CncResource這二個專案就沒有需要另外修改的地方,再檢查POM是否與剛才更新的縣市端專案的函式庫版本相同

若沒狀況,到此就完成合併的作業,編譯通過後重新發佈更新後的專案程式war檔

 

三、修改cncaccountdatasource

3-1 pull master branch

3-2 先在git上建立分支,名稱像是xxdatasource

3-3 修改POM的artifactId及version

<artifactId>xxaccountdatasource</artifactId>
<version>0.0.1</version>

3-4 修改CNCAccountSource程式

位置在cncaccountdatasource專案下->src->main->java->account

在 implement之後,新增一個方法,以讀取設定檔

 private static final Settings settings = new Settings() {
        @Override
        protected String getDefaultPropertiesFileName() {
            return "xxsyncdata.properties";
        }
    };

return "xxsyncda.properties"名稱是要給本部程式辨認的所以修改為縣市代號如新竹市就hcsyncdata.properties

這個設定檔是給本部帳號管理程式讀取的,只要在這支程式裡改名就可以了

再到下面第三個建構式這邊修改為各縣市回傳的資料型態,多種型態可用switch判斷

/**
 * @param identity      真實要送入的資料
 * @param iUniqueIDType 帳號型式,有GUID、ID、NAME以及USERNAME
 * @return
 */
@Override
public Optional<List<ExchangeDataModel>> getAccountData(String identity, IUniqueIDType iUniqueIDType) {
    Optional<List<ExchangeDataModel>> models = Optional.empty();
    //新竹市支援帳號ACCOUT反查
    switch (iUniqueIDType) {
        case ACCOUNT:
        case PERSONID:
            final Map<IUniqueIDType, String> iUniqueIDTypeStringMap = Collections.synchronizedMap(new HashMap<>());
            iUniqueIDTypeStringMap.put(iUniqueIDType, identity);
            DataRequest dataRequest = new DataRequest(settings,

//這邊直接傳入在本機測試用的設定檔路徑,自建一個client.properties檔案,內容為帳號管理平台的clientid & secrets
                    "../client.properties",//需指定本機測試用的檔案路徑
                    iUniqueIDTypeStringMap);

            logger.info("Map : {}", dataRequest.getiUniqueIDTypeStringMap());

            Future<Optional<List<ExchangeDataModel>>> future
                    = executorService.submit(dataRequest);

            try {
                models = future.get();
            } catch (InterruptedException | ExecutionException e) {
                logger.error("Cannot fetch ExchangeDataModel\n{}", e.getMessage());
                e.printStackTrace();
            }
            break;

        default:
            throw new UnsupportedOperationException();
    }

    return models;
}

 

client.properties檔案內容如下:就是開給帳號管理平台用的

###############################

clientid=要寫入帳號管理平台的id 
 clientsecret=要寫入帳號管理平台的secret 
 tokenuri=https://xx.sso.edu.tw/cncresource/api/v1/oauth2/token 
 syncdatauri=https://xx.sso.edu.tw/cncresource/api/v1/oauth2/syncdata

###############################

xx.sso.edu.tw要改成縣市端的主機網域

最後修改指定帳號來源的方法,回傳縣市端的代碼物件

/**
     * 指定帳號來源
     *
     * @return
     */
    @Override
    public AccountSource getAccountSource() {
        //TODO 指定資料來源
        return AccountSource.XXX;//縣市端代碼,例如:AccountSource.HC
    }

 

3-5 修改LocalExecution程式,在本機跑測試用

程式位置在src->main->java->execution->LocalExecution.java

在大約第46行的地方,改成要判斷的syncdata回傳資料型態

iUniqueIDTypeStringMap.put(IUniqueIDType.ACCOUNT, "test");

像新竹市可用帳號判斷,IUniqueIDType改用ACCOUNT,並直接帶入測試用的帳號名稱

下一行取設定檔的路徑也要修改

DataRequest dataRequest = new DataRequest(settings,
        "../client.properties",
        iUniqueIDTypeStringMap);

再下一行可以換不同的IUniqueIDType以測試是否可用其他資料型態如PERSONID反查

 

3-6 修改 test package下面的測試程式

位置在src->test->java->RequestTest.java

修改方式同上,改成要判斷的syncdata回傳資料型態IUniqueIDType

 

四、上傳並更新cncauthserver及CncResource程式

重新發佈二個程式後,到縣市IDP本地管理頁面,使用管理帳號登入修正應用程式的flow及scpoe選項,如下圖

如果前面步驟合併分支成功,scope選項會多出一個syncdata可勾選, oauth flow會多出token及client_credentials可勾選

帳號管理平台

 

本部認證程式

 

五、編譯專案後,執行測試程式(右鍵run)

簡單執行流程如下:

新建帳號平臺選完學校,輸完個資,按下一步,會呼叫SPI

SPI的執行會先產生ExecutorService(Wildfly自動產生),然後把呼叫遠端SYNCDATA API的工作交給另一個執行緒執行

該執行緒會去取得TOKEN,並且以非同步(另一個執行緒)來問SYNCDATA REST API

 

如果成功,就會在終端機畫面看到回傳的資料了,長得像這樣

08 Aug 2019 16:06:32,210 execution.DataRequest execution.DataRequest.fetchAccessToken(DataRequest.java:120)
Bearer Access Token : {"access_token":"E8gpzjEUfU12hIPMJoq_Kd1nZHzI9mHuCg0KibG1vIo","scope":"syncdata","token_type":"Bearer","expires_in":3600}
08 Aug 2019 16:06:32,376 assets.tools.CNCUtils assets.tools.CNCUtils.getISODateTime(CNCUtils.java:775)
ISO DateTime -> 2019-08-08T08:06:32.355Z

08 Aug 2019 16:06:32,390 assets.tools.CNCUtils assets.tools.CNCUtils.addExpireDT(CNCUtils.java:567)
Expire DateTime -> 2019-08-08T09:06:32.355Z
08 Aug 2019 16:06:32,390 RequestTest RequestTest.doTest(RequestTest.java:31)
Map : {縣市帳號=test}
08 Aug 2019 16:06:32,394 assets.tools.CNCUtils assets.tools.CNCUtils.getISODateTime(CNCUtils.java:775)
ISO DateTime -> 2019-08-08T08:06:32.394Z

08 Aug 2019 16:06:32,696 execution.DataRequest execution.DataRequest.fetchSyncData(DataRequest.java:149)
Map : {縣市帳號=testc}
08 Aug 2019 16:06:33,207 execution.DataRequest execution.DataRequest.fetchSyncData(DataRequest.java:160)
Json : {"ACCOUNT":"testc"}
08 Aug 2019 16:06:34,097 execution.DataRequest execution.DataRequest.fetchSyncData(DataRequest.java:166)
Data : [{"username":"test","fullname":"測試","email":"hcstudy@hc.edu.tw","schoolid":"183306","titles":[{"schoolid":"189999","titles":["教師","教學設備組組長"]},{"schoolid":"183306","titles":["教師","教學設備組組長"]}],"classinfo":[{"year":null,"semester":null,"schoolid":"189999","grade":"","classno":"","classtitle":"年班"},{"year":null,"semester":null,"schoolid":"183306","grade":"","classno":"","classtitle":"年班"}],"educloudroles":{"usage":"教育雲","roles":[{"appname":"edumail","schoolid":"189999","titles":["教師","教學設備組組長"]},{"appname":"edumail","schoolid":"183306","titles":["教師","教學設備組組長"]}]},"guid":"c48b8904faf5f9c47c747516c8737690cb68244f934bd40c29ad7734e7","pid":"C123456789","openid":"https://openid.edu.tw/user/test"}]