- 服务描述
- 主要API
- API GET /biometric-login 指纹登录
- API POST /biometric-login 指纹登录
- API /biometric-login/register
- API /biometric-login/deregister
- API /ndi/biometric-login/{action}
- API /pre-login/parameter GET
- API /pre-login POST 注册/激活网上银行
- API /pre-login/verify POST
- API /accesscode-login GET 用户名登录,获取登录所需参数
- API /accesscode-login POST 用户名登录
- API /accesscode-login/change-password GET accesscode login修改密码
- API /accesscode-login/change-password POST accesscode login修改密码
- API /accesscode-login/change GET accesscode login修改loginID
- API /accesscode-login/change POST accesscode login修改loginID
- API /accesscode-login/accesscode/change POST 修改accesscode
- API /accesscode-elevation/elevate POST
- API /singpass-login POST Singpass登录
- API /tnc/update
- API GET /user-info
- API POST /user/retrieve
- API /user-management/access
- API /logout 登出
- API trouble-login/init POST
- API trouble-login/retrieve POST
- API trouble-login/submit POST
- 主要业务流程
- 主要架构设计方案
- 主要数据库设计
- 遇到的问题和解决方案
- 优缺点和改进方案分析,业界对比
服务描述
负责用户登录鉴权的服务。
用户注册开卡的服务:ms-onshore-onboarding,ms-offshore-onboarding。
用户注册/激活网上银行: /pre-login。
用户登录:/access-code/login。
主要API
API GET /biometric-login 指纹登录
调用IAccessCodeLoginService的具体实现类的loginLoadParameter()方法,获得Random Id和Random Num。
调用CryptoClientService类的storeRandomNumber()方法,为了后续验证。
TansactionSequenceNumber和ResponseCode。
其他参数包括modulusString模数,exponent指数,minLength,maxLength,maxLoginIdLength通过配置文件获取。这些参数是Region、API level。
比如setPassword、preLoginLoadParam、accesscodeLogin、biometricLogin、biometricRegistration。
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(modulus, exponent));
API POST /biometric-login 指纹登录
流程:
校验Pin。
调用EBS和cust-profile,校验用户状态。
同步用户状态,INB和MS。
对shadow mode login,调用UAS/v1/VerifyOTP。
创建IdToken。
AFMS校验。
FMS校验。
调用ms-auth创建x-acc-op。
校验Routing indicator,返回smsRegistered flag。
更新IdToken,如果indicator是security check required。
调用USP更新INB,用户成功登录的信息。
更新usr_auth表和usr_reg表。
更新user.cifNo,调用USP更新INB。
调用USP更新INB,disable session。
把调用EBS的结果放入缓存。
API /biometric-login/register
API /biometric-login/deregister
API /ndi/biometric-login/{action}
disable、enable、解锁卡。
API /pre-login/parameter GET
获取调用Pre Login接口所需参数,包括modulusString、exponent、minLength、maxLength、maxLoginIdLength、randomNumber、randomID、transactionSequenceNumber、responseCode。
V2 MY,通过调用SOA CBS-GetRandomNumber-I,获取randomID和randomNumber,其他参数从配置文件获得。
V1 SG,
存储randomID、randomNumber、expiresAt到random_no_history表。
API /pre-login POST 注册/激活网上银行
用户注册/激活网上银行。把用户信息存储到DB,包括用户的密码密文。
| 请求参数 | 描述 |
|---|---|
| x-acc-jwt | JWT包括cif_no、card_no、legal_id、id_type、id_country、login_id。 用户开卡是注册网上银行的前提。 |
| x-acc-op | |
| cString | 前端JS通过pin、newPin、randomNo、modulusString、exponent计算得到。 以上参数通过调用/pre-login/parameter GET获取。 |
| pString | 同上。 |
| randomId | 通过调用/pre-login/parameter GET获取。 |
| maskedPassword | 开卡成功后提供给用户的默认网上银行密码。 SG流程:将被存储到usr_auth表encry_pwd字段。 |
| loginId | 如果为空,以JWT.loginId代替。 存储到usr表login_id字段。 |
| 响应参数 | 描述 |
|---|---|
| status | 是否成功 OK |
流程
1. 校验请求参数。
2. 如果是V2 MY,查询usr表,如果存在loginId则返回错误码。
如果是V2 MY
3. 调用ms-crypto/internal/pin/create,创建密码。ms-crypto调用HSM(负责加解密),并把loginId/密码密文保存到本地。
调用EBS-PSCustLoginID-C,创建access code。
如果是V1 SG
3. 调用EBS-OnlineINBAccessCodeApp-CU,创建密码和access code。
4. 异步调用ms-fraud-surveillance/fms/check,校验。
5. 在usr和usr_auth表中创建记录(pin/accessCode/cifNo),如果coexistence.write=ON,调用USP存储过程,同步到INB DB。
6. 异步调用ms-customer-profile/internal/user/create创建用户,retail_customer / CUSTOMER / CUSTOMER_CONTACT表。
7. 发送Kafka消息,给ms-audit和ms-customer-notification。
API /pre-login/verify POST
在登录之前校验参数。可以在POST /pre-login之前调用。
| 请求参数 | 描述 |
|---|---|
API /accesscode-login GET 用户名登录,获取登录所需参数
获取登录参数,包括modulusString、exponent、minLength、maxLength、maxLoginIdLength、randomNumber、randomID、transactionSequenceNumber(only SG)、responseCode(only SG)。
以上参数大多配置在配置文件中。前端获取到这些参数后,通过JS计算得到pString和cString,然后调用/accesscode-login POST接口。
流程
1、调用ms-crypto,产生randomID和randomNumber,存储到RandomNumber表和缓存。
2、从配置文件中获取参数,modulusString、exponent等。
3、从缓存pinPolicyCache获取modulusString、exponent。
API /accesscode-login POST 用户名登录
access code登录接口。
| 请求参数 | 描述 |
|---|---|
| x-source-app | |
| loginId | 用户名 |
| rid | 在调用preLogin接口时创建并缓存。如果缓存没有则抛出异常ACL-5036 |
| pString | |
| cString | |
| password | |
| loginMode | INB, NETS, FPX, IPA, EGIRO, MBS, OPENBANKING_CONSENT, ONBOARDING, ACCT_OPENING_CORP |
| transactionContextId | |
| afmsSessionId | |
| authorizationId | |
| transactionType | |
| captchaToken | JSONObject,验证码 |
| captchaToken->captchaId | |
| captchaToken->value | |
| deviceInfo | JSONObject,设备信息 |
| deviceInfo->fpt | |
| deviceInfo->tid | |
| deviceInfo->tsn | |
| deviceInfo->device |
| 响应参数 | 描述 |
|---|---|
| referenceNo | 格式:yyyyMMdd+6 random num |
| trxDateTime | 2025-03-10 |
| routeIndicator | 导航码 0 LOGIN 1 SUCCESS 3 TERMS 7 HWK_NEW_TOKEN_REQUEST 8 NEW_TOKEN_BIND 9 LOGIN_OTP 15 FORCE_CHANGE_PIN 16 REQUIRE_CAPTCHA 17 ELEVATE 18 SMS_TOKEN_ACTIVATION 19 TOKEN_PREFERENCE 20 REQUIRE_SECURITY_IMAGE 21 SOFTTOKEN_INTRO 23 SOFTTOKEN_SUBSEQ_ACTIVATION 24 SOFTTOKEN_NEW_TO_BANK_ACTIVATION 25 SOFTTOKEN_SHADOW_ACTIVATION 26 SOFTTOKEN_AUTO_PROVISION 31 FUID_SETUP FAIL FAIL |
| securityImage | |
| securityPhrase |
调用IAccessCodeLoginService的具体实现类的accessCodeLogin()方法,下面以AccessCodeLoginSoaServiceImpl类为例。
1. 校验请求信息check security image。
如果PString,CString和password为空,则查询Usr表获取sec_img_cd,通过SecurityImgPhraseCommonService类调用ms-reference-data接口,获取securityImage和securityPhrase,同时返回200,且routingIndicator=20。
1.1 校验验证码Captcha
通过调用ms-captcha服务的/captcha/validate接口进行校验。
1.2 校验请求参数
通过AccessCodeLoginCommonServiceImpl类的validateMandatoryAccessCodeLoginRequest()方法。
2. 登录流程
校验账户的状态。
发送kafka
返回响应头,包括x-acc-op,x-ref-op等。
返回响应体,包括reference no,trx datetime,route indicator,expire in。
流程:
获取resourceId。
通过工具类创建trxRefNo。
校验是否IPA flow。
如果request.txnId为空
校验loginId。
如果是IPA flow,通过loginId,调用USP查询INB old DB。
否则先查本地usr表,如果记录为空再查INB old DB。
调用ms-crypto返回randomID和randomNumber,存储到RandomNumber表和缓存。
存储到usr_authorization表。
如果request.txnId不为空
1. 校验prelogin和randomID。
注:什么是prelogin?用户注册网上银行。
2. 校验安全图片Security image。
注:Security image安全图片是在用户注册时由用户从系统预设的图片库中选择的一张图片,并附上用户自己设定的注释。在每次登录时,系统会显示这张图片和注释,作为用户验证身份的一种方式。其主要目的是增加一层额外的安全验证,以防止钓鱼网站和其他形式的网络攻击。
3. 校验验证码Captcha,调用ms-captcha。
4. 校验pString,cString,password,rId。
5. 登录流程,返回Routing Indicator路由码。
注:什么是pString,cString?前端JS通过pin、newPin、randomNo、modulusString、exponent计算得到的字符串。
6. 校验用户账号状态,比如是否被锁
调用ms-accounts/查询inb db。
7. 校验loginId/密码密文
调用ms-crypto/internal/pin/verify。
8. 本地生成JWT。
9. 获取用户各种账号信息
调用ms-accounts/internal/all-account,比如casa、card、loan等。
10. 失效INB DB的用户session
异步通过调用INB USP。
11. 撤销用户token,
异步调用ms-auth/token/revoke。
12. 校验FMS
异步调用ms-fraud-surveillance/internal/fms/check。
13. 校验AFMS
异步调用ms-fraud-management/v4/risk-score/retrieve,存储到缓存。
14. 创建用户token
调用ms-auth/athorization/secure-token,获取一对短token并返回。
API /accesscode-login/change-password GET accesscode login修改密码
获取参数。
API /accesscode-login/change-password POST accesscode login修改密码
修改密码。
API /accesscode-login/change GET accesscode login修改loginID
获取参数。
API /accesscode-login/change POST accesscode login修改loginID
修改loginID。
API /accesscode-login/accesscode/change POST 修改accesscode
TBC=====================
API /accesscode-elevation/elevate POST
校验pin。
API /singpass-login POST Singpass登录
流程:
1. 生成随机码referenceNo。
2. 校验nonce和singpass。
调用singpass.gov.sg/token,校验clientID,ecSignKey,aliasSignPrivatekey,codeVerifier
3. 检查loginMode。
如果不在配置名单NETS,FPX,OPENBANKING_CONSENT,EGIRO,IPA,返回null。
4. 校验partner Auth。
从缓存获取partnerAuthPolicy,通过policyCode,authType。
5. 获取loginId/cifno/accessCode
调用customer-profile/cif/inquiry → SOA EBS-CheckDuplicateCIF-I。
6. 校验account 状态
通过accessCode查询ms DB或INB USP。
如果用户不存在本地DB,查询INB。
7. 校验用户状态,调用EBS
获取用户mobileNo,调用customer-profile?
8. 更新用户信息和状态到INB DB
9. 如果用户本地不存在,但是INB存在,则本地新建用户
10. 如果是shadow mode登录,异步调用UAS,校验OTP,OTP在请求体吗?
11. 创建custom JWT
12. 更新cifno,在本地DB和INB
13. 校验AFMS。
14. 创建token
调用ms-auth/authorization/secure-token
15. 把JWT放到请求头x-acc-jwt
16. 校验FMS,调用ms-fraud-surveillance/internal/fms/check
17. 检查routingIndicator
18. 校验first time singpass login
19. 失效INB session
TBC=====================
调用Singpass,生成并返回JWT。
校验JWT.AUD和clientID是否匹配。
API /tnc/update
tnc: terms AND conditions 条件和条款。
询问用户是否接受tnc。如果接受则继续,否则返回错误并终止。
API GET /user-info
获取用户JWT信息,返回JSON字符串。
API POST /user/retrieve
查询用户登录loginID。
如果txnID不为空,调用cust-auth查询状态。
如果txnID为空或者状态为Failed,调用cust-auth TAC流程。
或者查询INB DB,如果loginID不为空,返回。如果为空,通过JWT的login_id,org_id,access_code字段,查询usr表。
API /user-management/access
一键禁用用户session和互联网访问权限(比如mobile、INB),实现KILL SWITCH。
API /logout 登出
API trouble-login/init POST
用户在登录/重置PIN过程中如果遇到问题,身份验证流程,通过调用ms-identity-assurance POST v1/internal/id-verification/init 触发用户ID验证。
API trouble-login/retrieve POST
通过调用ms-identity-assurance POST v1/internal/id-verification/submit获取用户identity token,通过identity token获取FUID。
API trouble-login/submit POST
身份验证流程的最终提交。
主要业务流程
主要架构设计方案
主要数据库设计
usr用户表
| Field | Remark |
|---|---|
| id | UUID |
| usr_status_code | |
| usr_status_mod_code | modify |
| usr_status_mod_remarks | |
| login_id | |
| login_group_id | |
| access_code | |
| cif_no | |
| first_login_tim | |
| last_success_login_time | |
| last_invalid_login_time | |
| login_invalid_ct | count |
| login_success_-ct | |
| last_tnc_accept | |
| sec_img_cd | |
| sec_phrase | |
| auth_group | |
| is_first_singpass_login | |
| captcha_invalid_ct | |
| attribute | JSONB |
| is_migrated | inbProfileMigrated |
usr_auth 用户登录表
| Field | Remark |
|---|---|
| id | UUID |
| auth_type | 登录类型,比如pwd,pwdv2, local_bio, signpass |
| login_group_id | |
| login_id | |
| encry_pwd | |
| algo | 算法类型,比如EBS,HSM,SSO |
| last_pwd_mod_time | |
| auth_json | |
| usr_reg_id | |
| source_app | |
| usr_id | UUID |
usr_reg 用户注册表
| Field | Remark |
|---|---|
usr_authorization
| Field | Remark |
|---|---|
| authorization_id | |
| session_id | |
| usr_id | |
| detail | Object, JSONB |
| trx_type |
遇到的问题和解决方案
优缺点和改进方案分析,业界对比
有重复代码,重复调用inb usp。
