# Single Sign-On

## Content

Forguncy에서 작성한 애플리케이션에서 다른 웹 애플리케이션 및 클라우드 서비스 자격 증명을 사용하는 소위 싱글 사인온을 구현하는 경우 인증 공급자의 사용을 고려하십시오.
인증 프로바이더로 실현이 불가능한 경우, 프로그래밍에 의한 커스터마이즈에 의해 싱글 사인온이 가능합니다. 이 섹션에서는 이러한 경우에 싱글 사인온 방법을 설명합니다. 이 기능은 Windows 인증에서는 사용할 수 없습니다.
Forguncy의 인증 연계 기능은 아래 그림과 같은 흐름으로 이루어집니다.

![](https://gcdocumentsitekrblob.blob.core.windows.net/document-site-files/images/4e3bfc58-e2a1-41a1-ac75-a0e383260d93/Gemini_Generated_Image_s7gdxds7gdxds7gd.png)

## **사용자의 토큰을 요청합니다.**

사용자의 토큰을 요청하려면 다음 사양을 충족하는 HTTP 요청을 수행합니다.

| **속성 이름** | **설명** |
| ----- | --- |
| 목적지 | http://<서버 이름>/<응용 프로그램 경로>/SSO/GetUserToken |
| HTTP 메소드 | POST |
| 메시지 본문 | 인증하려는 Forguncy 사용자 이름과 인증 연동 암호가 있는 JSON 예) {userName:"user1", password:"6s6s6s6s6s6s"} |

위의 메시지 본문에 포함된 비밀번호는 다른 응용프로그램에서 로그인을 허용할 때 설정된 응용프로그램에 공통인 비밀번호입니다. 이 암호는 다음 위치에서 확인 및 변경할 수 있습니다.

> 사용자이름은 Forguncy의 사용자 관리 시스템에 존재하여야 합니다.

## 

**[파일] → [옵션] → [기타 응용 프로그램과 통합]을 선택하여 [기타 응용 프로그램과 통합]을 선택합니다.**
다른 응용 프로그램에서 로그인 허용을 선택하지 않으면 사용자의 토큰을 요청할 수 없습니다.

![image](https://gcdocumentsitekrblob.blob.core.windows.net/document-site-files/images/4f96589d-8403-419e-b2a1-4f6776199cb9/image-20261007.71ae90.png)

| 설정 | 설명 |
| --- | --- |
| 기타 응용 프로그램의 서명 허용 | Single Sign-On을 활성화할지 여부. 기본값은 False입니다. |
| 로그인 암호 | 사용자 토큰을 얻는 데 필요한 비밀번호입니다. 디자이너를 열면 비밀번호가 무작위로 생성됩니다. Single Sign-On을 허용한 후 파일을 저장하지 않으면 다음에 파일을 열 때 비밀번호가 다시 생성됩니다. 파일을 저장하면 다시 열 때 비밀번호가 변경되지 않습니다. |
| 토큰 시간 제한 | 토큰의 유효 기간. |

2. **사용자 토큰을 받습니다.**
    토큰을 요청하는 HTTP 요청이 성공하면 토큰이 응답으로 반환됩니다. 토큰을 요청하는 HTTP 요청이 실패하면 반환되는 토큰은 "Error:" 문자열로 시작합니다.
    **3\. 토큰을 쿼리 문자열\(URL 매개 변수\)로 지정하여\, 이동하려는 Forguncy 애플리케이션 페이지로 이동합니다\.**
    http://<서버명>/<응용프로그램>/?token=1h1h1h1h-1h1h-1h1h-1h1h-1h1h1h1h1h1h
    2단계에서 토큰을 받은 후 3단계를 수행할 때까지의 제한 시간은 기본적으로 10초로 설정됩니다. 이를 변경하려면 다음과 같이 하십시오.
    [파일] → [옵션] → [애플리케이션 연동]을 선택하고 [토큰 시간 제한]을 변경합니다.
    ![image](https://gcdocumentsitekrblob.blob.core.windows.net/document-site-files/images/4f96589d-8403-419e-b2a1-4f6776199cb9/image-20261007.4d81c8.png)

**샘플 코드**
다음은 C# 샘플 코드 두 가지입니다.
Forguncy 애플리케이션이 HTTPS 통신을 사용하거나 기존 애플리케이션과 신뢰할 수 있는 네트워크에 있는 경우에는 이전 샘플 코드를 사용하십시오.

```auto
// 이전
internal class Program
    {
        static HttpClient client = new HttpClient();
        static async Task Main(string[] args)
        {
            var baseUrl = "http://localhost:47054/Forguncy";
            var userName = "administrator";
            var password = "@ddRUvpPgb^6";

            var ssoResponse = await client.PostAsync(baseUrl + "/SSO/GetUserToken", JsonContent.Create(new Dictionary
            {
                {"userName",userName },
                {"password",password }
            }));

            var token = await ssoResponse.Content.ReadAsStringAsync();

            if (token.StartsWith("Error:"))
            {
                Console.WriteLine(token);
                return;
            }
            var str = baseUrl + "?token=" + token;
        }
    }
```

```csharp
// 신규
internal class Program
    {
        static HttpClient client = new HttpClient();
        static async Task Main(string[] args)
        {
            var baseUrl = "http://localhost:52839/Forguncy";
            var userName = "administrator";
            var password = "Nk0u1w&yXqwh";
            var publicKeyRespose = await client.PostAsync(baseUrl + "/SSO/GetRSAPublicKey", null);
            var publicKey = await publicKeyRespose.Content.ReadAsStringAsync();
            var encryptPassword = EncryptDataWithPemPublicKey(password, publicKey);
            var ssoResponse = await client.PostAsync(baseUrl + "/SSO/GetUserToken", JsonContent.Create(new Dictionary
            {
                {"userName",userName },
                {"password",encryptPassword },
                {"publicKey",publicKey },
            }));
            var token = await ssoResponse.Content.ReadAsStringAsync();
            if (token.StartsWith("Error:"))
            {
                Console.WriteLine(token);
                return;
            }
            var str = baseUrl + "?token=" + token;
        }
        public static string EncryptDataWithPemPublicKey(string dataToEncrypt, string pemPublicKey)
        {
            using RSA rsa = RSA.Create();
            rsa.ImportFromPem(pemPublicKey.ToCharArray());
            byte[] dataBytes = Encoding.UTF8.GetBytes(dataToEncrypt);
            byte[] encryptedData = rsa.Encrypt(dataBytes, RSAEncryptionPadding.Pkcs1);
            return Convert.ToBase64String(encryptedData);
        }
```

> * 이 기능은 Form 사용자에게만 제공되며 Windows 도메인 사용자는 사용할 수 없습니다.
> * 로그인에 필요한 사용자 이름은 Forguncy 애플리케이션에 이미 존재해야 합니다.
> * 보안을 강화하려면 Single Sign-On 비밀번호가 JavaScript 코드에 나타나서는 안 됩니다. 그래야 유출을 방지할 수 있습니다.

## **배포 후 비밀번호를 바로 변경하세요.**

서버의 "C:\\Users\\Public\\Documents\\ForguncyServer\\ *Application Name* " 디렉토리에서 "Config.xml" 구성 파일을 찾아 열고 아래 그림과 같이 Password 값을 편집합니다.

![](https://gcdocumentsitekrblob.blob.core.windows.net/document-site-files/images/4e3bfc58-e2a1-41a1-ac75-a0e383260d93/image-2612.png)

> * 비밀번호 노드에 값이 없으면 빌더가 열릴 때 비밀번호가 무작위로 생성된다는 의미입니다.
> * 수정 후에는 웹사이트를 다시 시작해야 합니다.