Adapter Setup Guide
Adapter Setup Guide
This is a description of the Adapter environment setup file. You must configure the environment before applying the ADFS Adapter.
Adapter Installation Location Change
From adapter 1.2.0.6, installation is possible on drives other than the C drive.
Existing : Only installed on C:/ADFSadapter
Change : Installed on the root of drives C to Z
Example: C:/ADFSadapter , D:/ADFSadapter , E:/ADFSadapter , …… , Z:/ADFSadapter
Precautions : It can only be installed on one drive, and if it is installed on multiple drives, the first discovered directory is used while scanning from C to Z
If installed on a drive other than C, only the drive name (drive letter) in the example below needs to be changed.
- Example: If installed in D:\ADFSadapter, the ini path → D:\ADFSadapter\ADFSadapter.ini
File Name and Path
- File Name: ADFSadapter.ini
- Full Path: C:\ADFSadapter\ADFSadapter.ini
- File Encoding: Must be saved in UTF-8 (Korean characters may be broken if not)
Things to Keep in Mind
* When expressing values, " and " can be used, and spaces can be entered on either side of the = sign.
+ Spaces before and after the Value are trimmed.
+ The following Values are all the same
+ Example 1) MAIN_TITLE = DWP MFA Adapter
+ Example 2) MAIN_TITLE = DWP MFA Adapter
+ Example 3) MAIN_TITLE = "DWP MFA Adapter"
+ Example 4) MAIN_TITLE = " DWP MFA Adapter "
* Some section names have -1033, -1042 appended to the end, which means locale.
+ At least 1033 must exist.
+ Locale number: 1033 (en-us), 1042 (ko)
+ Locale section: MFA-1033, MFA-1042, TXT-1033, TXT-1042, MSG-1033, MSG-1042
Ini File Structure Example
Some values in the example settings below are masked for security purposes, and the actual values are not asterisks
# ADFS MFA Adapter Environment Settings
# Installation Location Changes
# - Before v1.2.0.6: C:\ADFSadapter\ADFSadapter.ini
# - From v1.2.0.6: Can be installed on a drive other than C (same location as adapter resource installation)
# Examples: C:\ADFSadapter\ADFSadapter.ini, D:\ADFSadapter\ADFSadapter.ini, E:\ADFSadapter\ADFSadapter.ini
# Note: The DLL file name is ADFSadapter.dll, which is different from the existing MFAadapter.dll linked to Nexsign
# When expressing values, " and ' can be used, and spaces can be entered on either side of =
# Leading and trailing spaces of the Value are trimmed.
# The following Values are all the same.
# Example 1) MAIN_TITLE=ADFS MFA Adapter
# Example 2) MAIN_TITLE = ADFS MFA Adapter
# Example 3) MAIN_TITLE = "ADFS MFA Adapter"
# Example 4) MAIN_TITLE = " ADFS MFA Adapter "
# Section names with -1033, -1042 at the end represent locale
# At least 1033 must exist
# Locale number: 1033 (en-us), 1042 (ko)
# Locale section: MFA-1033, MFA-1042, TXT-1033, TXT-1042, MSG-1033, MSG-1042
# LOG_LEVEL (Windows event log recording criteria)
# 0: Error
# 1: Error + Warning
# 2: Error + Warning + Information + Debug
[MAIN] MAIN_MFA_TITLE=“ADFS MFA Adapter” MAIN_CLAIM1=http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod MAIN_CLAIM2=http://schemas.microsoft.com/ws/2012/12/authmethod/otp
MFA API Information
Do not add “/” at the end of the URL
#MFA_API_URL=“https://stg2-cloud.singleid.samsung.net/test/common-api/open/v1.1/mfa/request" MFA_API_URL=“https://stg1-cloud.singleid.samsung.net/test/common-api/open/v1.1/mfa/request" CONSUMER_KEY=”” SECRET_KEY=""
Domain vs Consumer Key List
If the Consumer Key is different for each domain, list it (in this case, leave the CONSUMER_KEY value above blank)
Insert the sys value of the Request Token
Format: DOMAIN_CONSUMER_KEY_##=domain;consumerKey
Example: DOMAIN_CONSUMER_KEY_01=aaa.com;**************************************
DOMAIN_CONSUMER_KEY_02=bbb.com;**************************************
(Note) If both CONSUMER_KEY value and list value exist, only the CONSUMER_KEY value is used
DOMAIN_CONSUMER_KEY_01=aaa.com;************************************** DOMAIN_CONSUMER_KEY_02=bbb.com;**************************************
Domain vs Secret Key List
If the Secret Key is different for each domain, list it (in this case, leave the SECRET_KEY value above blank)
Format: DOMAIN_SECRET_KEY_##=domain;secretKey
Example: DOMAIN_SECRET_KEY_01=aaa.com;**************************************
DOMAIN_SECRET_KEY_02=bbb.com;**************************************
(Note) If both SECRET_KEY value and list value exist, only the SECRET_KEY value is used
DOMAIN_SECRET_KEY_01=aaa.com;************************************** DOMAIN_SECRET_KEY_02=bbb.com;**************************************
LDAP Search result-based MFA progress
0 : Do not perform LDAP Search (do not use the information below, such as LDAP_SERVER, LDAP_USE_IDPW, etc. Insert an empty value into the token)
1 : Attempt LDAP Search, but failure is irrelevant (proceed with MFA even if server failure or no information occurs. Insert an empty value into the token)
2 : LDAP Search must be successful and user information must exist (proceed only when user information exists. However, proceed even if the result value is empty)
USE_LDAP_SEARCH=1
LDAP address and ID/PW
LDAP_SERVER can be domain, ipv4, ipv6, etc., and the upper case “LDAP://” must be attached to the front (must be upper case)
Example: LDAP://adpw5004.hw.dev , LDAP://70.2.180.218 , LDAP://fe80::644b:3c9f:c5ac:ce1c%10
Set LDAP_USE_IDPW to 1 to use ID/PW, and set LDAP_USE_IDPW to 0 not to use
Set LDAP_SSLTLS to 1 to use SSL/TLS, and set LDAP_SSLTLS to 0 not to use (only applicable when LDAP_USE_IDPW=1)
LDAP_SERVER=“LDAP://adpw5004.hw.dev” LDAP_USE_IDPW=1 LDAP_SSLTLS=1 LDAP_ID=“isadmin” LDAP_PW=“sds*****”
Perform DNS Lookup to check the IP address of the LDAP server (LDAP_SERVER) and connect based on the IP address
Even if the LDAP_SERVER value is set to IP (ipv4, ipv6), DNS Lookup is performed, and the IP is returned as is
If DNS Lookup fails, connect using the LDAP_SERVER value as is
0 : Connect to the server using the LDAP_SERVER value as is (do not perform DNS lookup)
1 : Connect to the LDAP server using the IP address confirmed by DNS lookup (use the first IP in the DNS lookup result list)
2 : Confirm the IP address using DNS lookup and use the IP that corresponds to the LDAP_WHITE_IP_## list first (use the LDAP_SERVER if not in the list)
3 : Confirm the IP address using DNS lookup and use the IP that corresponds to the LDAP_WHITE_IP_## list first (do not connect to the LDAP if not in the list)
LDAP_DNS_LOOKUP=1
DNS Lookup result has multiple entries, try to connect to the next IP address if the first one fails
Example: 4 lookup results: 1st IP connection fails -> try 2nd IP & fail -> try 3rd IP & fail -> try 4th IP
LDAP_DNS_IF_FAIL_USE_NEXT=1
List of allowed LDAP server IP addresses to compare with DNS Lookup results (only applicable when LDAP_DNS_LOOKUP = 2 or 3)
In the format of LDAP_WHITE_IP_##, recorded sequentially from 01 to 99
Compare DNS Lookup results with the list in sequence
Record in IPv4 or IPv6 format (if the same server has both IPv4 and IPv6, the one with higher priority in the list is applied)
If the order of DNS Lookup results and White IP list is different, follow the order of White IP list
LDAP_WHITE_IP_01=“70.2.180.218” LDAP_WHITE_IP_02=“fe80::644b:3c9f:c5ac:ce1c%10”
Whether to encrypt user information (e.g., mobile, email, etc.)
Target: USERINFO_## list
The name of the claim in the token sent to the API server varies depending on whether encryption is used
0: Do not encrypt -> claim name in token is plainMobile, plainEmail
1: Encrypt -> claim name in token is mobile, email
USERINFO_ENCRYPT=0
LDAP Search user information attribute name and JWT token claim name (delimiter between two values = “;”)
Format: USERINFO_## = attribute;encryptedClaim;plainClaim
Example: If the “mail” attribute is read from LDAP and used as the “email” claim in JWT, then “mail;email;plainEmail”
Key name is in the format “USERINFO_##” and starts with USERINFO_01
Number of keys: 0 to a maximum of 99 (if there are no keys, do not write anything in the ini file, and do not write USERINFO_00)
Note) The number in USERINFO_## should start from 01 and should not be interrupted if there are multiple keys
USERINFO_01, USERINFO_02, USERINFO_03 : OK (01, 02, 03 information is used)
USERINFO_01, USERINFO_02, USERINFO_05 : 02 is read and subsequent numbers are not used (01, 02 information is used)
USERINFO_01=mobile;mobile;plainMobile USERINFO_02=mail;email;plainEmail
MFA API server callback result parameter key name
Example: https://adpw5004.hw.dev/adfs/ls?client-request-id=xxxxxx&pullStatus=0&jwtTokenResponse=yyyyyy
KEY_NAME_IN_RESPONSE=“jwtTokenResponse”
JWT Token exp additional value
Format: dhms (day, hour, minute, second) string -> 1d=86400, 1h=3600, 1m=60 (numbers without dhms are considered seconds)
Example1: 1d02h38m27s -> 95907 seconds
Example2: 12345 -> 12345 seconds
TOKEN_EXP_TIME=1d
Whether to add client claim to the token when calling the API
client: issuer for SAML, client-id for OIDC
0: do not include client in token
1: include client in token
TOKEN_CLAIM_CLIENT=0
MFA nonce (guid, request-id) verification method
0: do not verify
1: adapter-generated guid is stored and compared in LDAP (adapter verifies)
-> related settings: CACHE_ATTRIBUTE, CACHE_DELIMETER, SKEW_SECONDS, CACHE_LIFE_TIME
2: API server-generated request-id is received by the adapter and used in the call URL (API server verifies)
-> Related setting value: MFA_VERIFY_URL
MFA_VERIFY_TYPE=2
MFA verification result URL (server-to-server communication): The URL is called by appending the {request-id} received from the API server to the end
The adapter checks if the return is 200 (OK) to process the MFA result
Do not attach a “/” at the end of the URL
MFA_VERIFY_URL=“https://stg1-cloud.iam.samsung.net/test/common-api/open/v1.1/mfa/request/status"
Security protocol used for MFA verification
Available protocols (case-insensitive): TLS12, TLS13
(Note) Do not use SSL3, TLS, TLS11
MFA_VERIFY_SECURE_PROTOCOL=“TLS12”
Name of the LDAP attribute to store the user’s req guid value
(Note) Write permission to LDAP is required
CACHE_ATTRIBUTE=“otherPager”
Delimiter used to combine req and time information when storing in LDAP -> “req;time”
CACHE_DELIMETER=”;"
Allowed time difference (in seconds) between the time stored in LDAP and the time the JWT is received
This is the time after AD login, not when the MFA selection screen is displayed (time is already stored when the MFA selection screen is displayed)
Therefore, the time should not be set too tightly, and around 1 hour is suitable?? (Is there anyone who takes 1 hour to select MFA?)
SKEW_SECONDS=3600
Time to live for req stored in LDAP -> Check time on next access and delete old ones
Format: String in dhms (day, hour, minute, second) format -> 1d=86400, 1h=3600, 1m=60 (numbers without dhms are considered seconds)
Example 1: 1d02h38m27s -> 95907 seconds
Example 2: 12345 -> 12345 seconds
CACHE_LIFE_TIME=1d
Whether to bypass Adapter functionality (0=normal use, 283901=disable, other values=normal use)
For emergency situations where MFA functionality issues require adapter functionality to be disabled
Do not modify this value under normal circumstances -> Normal value is 0
Note: To disable, the exact value must be set (not just any non-zero number, exact number required to avoid noise)
BYPASS_ADAPTER=0
[API] API_SYSTEMNAME=SingleID
[MSG-1033] MSG_INTERNAL_ERROR=“Internal error occurred. Contact administrator.”
[MSG-1042] MSG_INTERNAL_ERROR=“Internal error occurred. Contact administrator.”
[MANAGE] LOG_LEVEL=2
# Setting Value Description
* **Fixed Value** : It means that the value displayed in the **Setting Value** column of the table below is used as is when installing the ADFS server.
* If you want to add a language other than English and Korean, you can add up to 2 sections.
* MSG-1033, MSG-1042
dss
Key
Setting Value (Example)
Fixed Value
Description
MAIN
MAIN_MFA_TITLE
ADFS MFA Adapter
O
HTML page title (no effect on MFA function)
MAIN_CLAIM1
http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod
O
Must apply the value on the left as is
MAIN_CLAIM2
http://schemas.microsoft.com/ws/2012/12/authmethod/otp
O
Must apply the value on the left as is
MFA_API_URL
https://stg2-cloud.singleid.samsung.net/test/common-api/open/v1.1/mfa/request
SingleID MFA API address- May vary depending on the tenant, so the exact address value must be confirmed
CONSUMER_KEY
4312a8b9-75c4-7897-89a7-89347f18943e
Consumer Key issued by SingleID
SECRET_KEY
gQgkyLVO6FR8vJkLtlgBiupsRM/ilgrbEfoKWRnhALd=
Secret Key issued by SingleID- Used for JWT Signature verification
- Absolutely do not disclose to the outside
DOMAIN_CONSUMER_KEY_01
4312a8b9-75c4-7897-89a7-89347f18943e
Domain vs Consumer Key list- If the Consumer Key is different for each domain, list it (in this case, the value of CONSUMER_KEY above should be emptied)
- Format: DOMAIN_CONSUMER_KEY_##=domain;consumerKey
- Example:
DOMAIN_CONSUMER_KEY_01=aaa.com;4312a8b9-75c4-7897-89a7-89347f18943e
DOMAIN_CONSUMER_KEY_02=bbb.com;96567780-2b12-23da-637c-9375a6502d5a
- (Note) If both CONSUMER_KEY value and list value exist, only CONSUMER_KEY value is used
DOMAIN_CONSUMER_KEY_02
96567780-2b12-23da-637c-9375a6502d5a
DOMAIN_CONSUMER_KEY_##
367c89d5-88f7-978a-9739-8ed21748f36b
DOMAIN_SECRET_KEY_01
gQgkyLVO6FR8vJkLtlgBiupsRM/ilgrbEfoKWRnhALd=
Domain vs Secret Key list- If the Secret Key is different for each domain, list it (in this case, the value of SECRET_KEY above should be emptied)
- Format: DOMAIN_SECRET_KEY_##=domain;secretKey
- Example:
DOMAIN_SECRET_KEY_01=aaa.com;gQgkyLVO6FR8vJkLtlgBiupsRM/ilgrbEfoKWRnhALd=
DOMAIN_SECRET_KEY_02=bbb.com;kgkWRnLygQhsRgrLVbtKlO6FiLdABupEgoMR8v/ilfJ=
- (Note) If both SECRET_KEY value and list value exist, only SECRET_KEY value is used
DOMAIN_SECRET_KEY_02
kgkWRnLygQhsRgrLVbtKlO6FiLdABupEgoMR8v/ilfJ=
DOMAIN_SECRET_KEY_##
dABupkRnLygQhsrLgWVRbt8vRgkLilLKlO1FioMgfJE=
USE_LDAP_SEARCH
0 or 1 or 2
MFA progress based on LDAP Search result- 0 : Do not perform LDAP Search (do not use the information below, such as LDAP_SERVER, LDAP_USE_IDPW, etc. and insert an empty value into the token)
- 1 : Try LDAP Search, but it doesn’t matter if it fails (proceed with MFA even if server failure, no information, etc. occurs, and insert an empty value into the token)
- 2 : LDAP Search must be successful and user information must exist (proceed only if user information exists, but proceed even if the result value is empty)
LDAP_SERVER
LDAP://adpw5004.hw.dev
LDAP address that can query AD user information- All three types, domain, ipv4, and ipv6, are possible, and “LDAP://” must be attached to the front
LDAP_USE_IDPW
0 or 1
Whether to use id/pw when accessing LDAP- The adapter operates with system privileges, so it is common to access LDAP without id/pw, but there are cases where it is not
- If an AD connection error occurs in the event log in a state where id/pw is not used for connection, it is necessary to set it to use id/pw for connection
- If this value is set to 1, LDAP_ID and LDAP_PW values must be set
LDAP_SSLTLS
0 or 1
Whether to use SSL/TLS when connecting to LDAP- Generally, set to use
LDAP_ID
LDAP connection id
LDAP connection id (when LDAP_USE_IDPW=1)
LDAP_PW
LDAP connection pw
LDAP connection pw (when LDAP_USE_IDPW=1)
LDAP_DNS_LOOKUP
0 or 1 or 2 or 3
Whether to perform DNS lookup to check the IP address of the LDAP server (LDAP_SERVER) and connect based on the IP address- 0 : Connect to the server with the LDAP_SERVER value as is (do not perform DNS lookup)
- 1 : Perform DNS lookup to check the IP address and connect to the LDAP server (use the first IP in the DNS lookup result list)
- 2 : Perform DNS lookup to check the IP address and use the first corresponding IP in the LDAP_WHITE_IP_## list (if not in the list, use LDAP_SERVER)
- 3 : Perform DNS lookup to check the IP address and use the first corresponding IP in the LDAP_WHITE_IP_## list (if not in the list, do not connect to LDAP)
| | LDAP_DNS_IF_FAIL_USE_NEXT | 0 or 1 | | When there are multiple DNS lookup results, whether to try the next IP address if the connection to the first IP address fails<ul><li> Example: 4 lookup results: 1st IP connection failure -> 2nd IP connection attempt & failure -> 3rd IP connection attempt & failure -> 4th IP connection attempt |
| | LDAP_WHITE_IP_01 | 70.2.180.218 | | List of allowed LDAP server IP addresses to compare with DNS lookup results (only applicable when LDAP_DNS_LOOKUP = 2 or 3)</li></ul><ul><li> In the format of LDAP_WHITE_IP_##, recorded sequentially from 01 to 99</li></ul><ul><li> Compared sequentially with DNS lookup results</li></ul><ul><li> Recorded in IPv4 or IPv6 format (if the same server has both IPv4 and IPv6, the IP in the higher priority list is applied)</li></ul><ul><li> If the order of DNS lookup results and White IP list is different, the order of the White IP list is followed </li></ul>|
| | LDAP_WHITE_IP_02 || |fe80::644b:3c9f:c5ac:ce1c%10 |
| | LDAP_WHITE_IP_## | | | A. : 01 ~ 99<br>White IP address (IPv4 or IPv6) |
| | USERINFO_ENCRYPT | 0 or 1 | | Whether to encrypt user information (e.g., mobile, email, etc.)<ul><li> Target: USERINFO_## list</li></ul><ul><li> Depending on the encryption, the claim name of the token sent to the API server is different</li></ul><ul><li> 0: Not encrypted -> token's claim name is plainMobile, plainEmail</li></ul><ul><li> 1: Encrypted -> token's claim name is mobile, email </li></ul>|
| | USERINFO_01 | mobile;mobile;plainMobile | O | LDAP search user information attribute name and JWT token claim name (3 values are separated by ";")<ul><li> Format: USERINFO_## = attribute; encryptedClaim; plainClaim</li></ul><ul><li> Example: If you read the "mail" attribute from LDAP and use the encrypted value as "email" claim and the plain value as "plainEmail" claim in JWT, then "mail;email;plainEmail"</li></ul> |
| | USERINFO_02 | mail;email;plainEmail | O | |
| | USERINFO_## | | | A. : 01 ~ 99<br>[LDAP attribute name];[encrypted token claim name];[plain token claim name] |
| | KEY_NAME_IN_RESPONSE | jwtTokenResponse | O | Key name used in the result parameter when the MFA API server calls back<ul><li> Example: https://adpw5004.hw.dev/adfs/ls?client-request-id=xxxxxx&pullStatus=0&jwtTokenResponse=yyyyyy</li></ul> |
| | TOKEN_EXP_TIME | 1d | | Value to be added to the exp of the JWT token<ul><li> String in the format of day, hour, minute, second (dhms)<br>1d=86400, 1h=3600, 1m=60</li></ul><ul><li> If dhms is not present, it is considered as seconds</li></ul><ul><li> Example 1: 1d02h38m27s -> 95907 seconds<br>Example 2: 12345 -> 12345 seconds</li></ul> |
| | TOKEN_CLAIM_CLIENT | 0 or 1 | | Whether to add the client claim to the token when calling the API<ul><li> Client: issuer in SAML, client-id in OIDC</li></ul><ul><li> 0: Do not include client in the token</li></ul><ul><li> 1: Include client in the token</li></ul> |
| | MFA_VERIFY_TYPE | 0 or 1 or 2 | | MFA nonce (guid, request-id) verification method<ul><li> 0: Do not verify</li></ul><ul><li> 1: Store and compare the guid created by the adapter in LDAP (verified by the adapter) -> related settings: CACHE_ATTRIBUTE, CACHE_DELIMETER, SKEW_SECONDS, CACHE_LIFE_TIME</li></ul><ul><li> 2: Use the request-id created by the API server and used by the adapter in the call URL (verified by the API server) -> related settings: MFA_VERIFY_URL</li></ul> |
| | MFA_VERIFY_URL | https://stg1-cloud.iam.samsung.net/test/common-api/open/v1.1/mfa/request/status | | MFA result verification URL (server-to-server communication): {request-id} received from the API server is appended to the end of the URL and called -> the adapter checks if the return is 200 (OK) to process the MFA result<ul><li> Do not add "/" at the end of the URL </li></ul>|
| | MFA_VERIFY_SECURE_PROTOCOL | TLS12 or TLS13 | | Secure protocol used for MFA result verification<ul><li> Selectable protocols (case-insensitive): TLS12, TLS13</li></ul><ul><li> (Note) Do not use SSL3, TLS, TLS11 </li></ul>|
| | CACHE_ATTRIBUTE | otherPager | O | Name of the LDAP attribute to store the user's req guid value |
| | CACHE_DELIMETER | ";" | | Delimiter used to combine req + time information when storing in LDAP -> "req;time" |
| | SKEW_SECONDS | 3600 | | Allowed difference in seconds between the time stored in LDAP and the time received in JWT<ul><li> The time when the user logs in to AD, not when the MFA selection screen is displayed (the time is already stored when the MFA selection screen is displayed)</li></ul><ul><li> Not the time it takes for the user to select MFA and enter the passcode</li></ul><ul><li> Therefore, do not set the time too tightly, and about 1 hour is suitable?? (Is there anyone who takes 1 hour to select MFA?) |
| | CACHE_LIFE_TIME | 1d | | Lifetime of the req stored in LDAP -> delete old ones when checking the time at the next access<ul><li> String in the format of day, hour, minute, second (dhms)<br>1d=86400, 1h=3600, 1m=60<br>(If dhms is not present, it is considered as seconds) </li></ul>|
| | BYPASS_ADAPTER | 0 or 283901 | | Whether to bypass the adapter function (0 = normal use, 283901 = disable, other values = normal use)<ul><li> Used in emergency situations where the adapter function needs to be disabled due to MFA issues</li></ul><ul><li> Do not modify it in normal situations -> the normal value is 0</li></ul><ul><li> Note: To disable, you must set the exact value (not just any number other than 0, but the exact number. Be careful of noise) </li></ul>|
|API | API_SYSTEMNAME | SingleID | O | (No effect on MFA function)|
| MSG-1033 | MSG_INTERNAL_ERROR | "Internal error occurred. Contact administrator." | | Message displayed to the user when the authentication process is stopped due to an error (English) |
| MSG-1042 | MSG_INTERNAL_ERROR | "Internal error occurred. Contact administrator." | | Message displayed to the user when the authentication process is stopped due to an error (Korean) <ul><li> If you enter Korean, an error occurs, so please enter it in English. </li></ul> |
|MANAGE | LOG_LEVEL | 0 or 1 or 2 | | Standard for recording in the Windows event log<ul><li> 0 = only error</li></ul><ul><li> 1 = error + warning</li></ul><ul><li> 2 = error + warning + notice, etc. all recorded </li></ul>|
<div class="figure-caption">
Table. Setting value description
</div>