Direct Line API 3.0의 인증Authentication in Direct Line API 3.0

클라이언트는 Bot Framework 포털의 직접 회선 채널 구성 페이지에서 가져오는 비밀 을 사용하거나 런타임에 가져오는 토큰 을 사용하여 직접 회선 API 3.0에 대한 요청을 인증할 수 있습니다.A client can authenticate requests to Direct Line API 3.0 either by using a secret that you obtain from the Direct Line channel configuration page in the Bot Framework Portal or by using a token that you obtain at runtime. 비밀 또는 토큰은 다음 형식을 사용하여 각 요청의 Authorization 헤더에 지정해야 합니다.The secret or token should be specified in the Authorization header of each request, using this format:

Authorization: Bearer SECRET_OR_TOKEN

비밀 및 토큰Secrets and tokens

직접 회선 비밀 은 연결된 봇에 속하는 모든 대화에 액세스하는 데 사용할 수 있는 마스터 키입니다.A Direct Line secret is a master key that can be used to access any conversation that belongs to the associated bot. 토큰 을 가져오는 데도 비밀 을 사용할 수 있습니다.A secret can also be used to obtain a token. 비밀은 만료되지 않습니다.Secrets do not expire.

직접 회선 토큰 은 단일 대화에 액세스하는 데 사용할 수 있는 키입니다.A Direct Line token is a key that can be used to access a single conversation. 토큰은 만료되지만 새로 고칠 수 있습니다.A token expires but can be refreshed.

비밀 키 또는 토큰 을 사용할지의 여부와 사용하는 시기를 결정하는 것은 보안 고려 사항을 기반으로 해야 합니다.Deciding when or if to use the secret key or a token must be based on security considerations. 비밀 키를 노출하는 것은 의도적으로 신중하게 수행하는 경우 허용될 수 있습니다.Exposing the secret key could be acceptable if done intentionally and with care. 실제로 이는 Direct Line에서 클라이언트가 합법적인지 알 수 있도록 하므로 기본 동작입니다.As matter of a fact, this is the default behavior because this allows Direct Line to figure out if the client is legitimate. 그러나 일반적으로 사용자 데이터를 유지하려는 경우 보안이 중요합니다.Generally speaking though, security is a concern if you're trying to persist user data. 자세한 내용은 보안 고려 사항 섹션을 참조하세요.For more information, see section Security considerations.

서비스 간 애플리케이션을 만드는 경우 직접 회선 API 요청의 Authorization 헤더에 비밀 을 지정하는 것이 가장 간단한 방법일 수 있습니다.If you're creating a service-to-service application, specifying the secret in the Authorization header of Direct Line API requests may be simplest approach. 클라이언트가 웹 브라우저 또는 모바일 앱에서 실행되는 애플리케이션을 작성하는 경우 비밀을 토큰(단일 대화에서만 가능하고 새로 고치지 않으면 만료됨)으로 교환하고 직접 회선 API 요청의 Authorization 헤더에서 토큰 을 지정할 수 있습니다.If you're writing an application where the client runs in a web browser or mobile app, you may want to exchange your secret for a token (which only works for a single conversation and will expire unless refreshed) and specify the token in the Authorization header of Direct Line API requests. 본인에게 가장 적합한 보안 모델을 선택합니다.Choose the security model that works best for you.

참고

직접 회선 클라이언트 자격 증명은 봇의 자격 증명과 다릅니다.Your Direct Line client credentials are different from your bot's credentials. 이 자격 증명을 사용하면 키를 별도로 수정할 수 있으며, 봇 암호를 공개하지 않고도 클라이언트 토큰을 공유할 수 있습니다.This enables you to revise your keys independently and lets you share client tokens without disclosing your bot's password.

직접 회선 비밀 가져오기Get a Direct Line secret

Azure Portal에서 봇에 대한 Direct Line 채널 구성 페이지를 통해 Direct Line 비밀을 가져올 수 있습니다.You can obtain a Direct Line secret via the Direct Line channel configuration page for your bot in the Azure Portal:

직접 회선 구성

직접 회선 토큰 생성Generate a Direct Line token

단일 대화에 액세스하는 데 사용할 수 있는 Direct Line 토큰을 생성하려면 먼저 Azure Portal의 Direct Line 채널 구성 페이지에서 Direct Line 비밀을 획득합니다.To generate a Direct Line token that can be used to access a single conversation, first obtain the Direct Line secret from the Direct Line channel configuration page in the Azure Portal. 그런 다음, 이 요청을 실행하여 직접 회선 비밀을 직접 회선 토큰과 교환합니다.Then issue this request to exchange your Direct Line secret for a Direct Line token:

POST https://directline.botframework.com/v3/directline/tokens/generate
Authorization: Bearer SECRET

이 요청의 Authorization 헤더에서 SECRET 을 직접 회선 비밀 값으로 바꿉니다.In the Authorization header of this request, replace SECRET with the value of your Direct Line secret.

다음 코드 조각은 토큰 생성 요청 및 응답의 예제를 제공합니다.The following snippets provide an example of the Generate Token request and response.

요청Request

POST https://directline.botframework.com/v3/directline/tokens/generate
Authorization: Bearer RCurR_XV9ZA.cwA.BKA.iaJrC8xpy8qbOF5xnR2vtCX7CZj0LdjAPGfiCpg4Fv0

토큰 매개 변수를 포함하는 요청 페이로드는 선택 사항이지만 권장됩니다.The request payload, which contains the token parameters, is optional but recommended. Direct Line 서비스에 돌려 보낼 수 있는 토큰을 생성할 때는 더 안전한 연결을 위해 다음 페이로드를 제공합니다.When generating a token that can be sent back to the Direct Line service, provide the following payload to make the connection more secure. 이 값을 포함하면 Direct Line이 사용자 ID와 이름의 추가적인 보안 유효성 검사를 수행하여 악의적 클라이언트에 의한 값 변조를 방지할 수 있습니다.By including these values, Direct Line can perform additional security validation of the user ID and name, inhibiting tampering of these values by malicious clients. 또한 이 값을 통해 Direct Line의 대화 업데이트 작업 보내기 기능을 개선하여 사용자가 대화에 참가하는 즉시 대화 업데이트를 생성하도록 할 수 있습니다.Including these values also improves Direct Line's ability to send the conversation update activity, allowing it to generate the conversation update immediately upon the user joining the conversation. 이 정보를 제공하지 않은 경우 사용자가 콘텐츠를 보내야 Direct Line이 대화 업데이트를 보낼 수 있습니다.When this information is not provided, the user must send content before Direct Line can send the conversation update.

{
  "user": {
    "id": "string",
    "name": "string"
  },
  "trustedOrigins": [
    "string"
  ]
}
매개 변수Parameter 형식Type DescriptionDescription
user.id 문자열string (선택 사항)Optional. 토큰 안에 인코딩할 사용자의 채널 특정 ID입니다.Channel-specific ID of the user to encode within the token. Direct Line 사용자의 경우 이 값이 dl_로 시작되어야 합니다.For a Direct Line user, this must begin with dl_. 각 대화마다 고유한 사용자 ID를 만들 수 있고 보안을 강화하기 위해 이 ID는 추측할 수 없어야 합니다.You can create a unique user ID for each conversation, and for better security, you should make this ID unguessable.
user.name 문자열string (선택 사항)Optional. 토큰 안에 인코딩할 사용자의 친숙한 표시 이름입니다.The display-friendly name of the user to encode within the token.
trustedOrigins 문자열 배열string array (선택 사항)Optional. 토큰 안에 포함할 신뢰할 수 있는 도메인 목록입니다.A list of trusted domains to embed within the token. 봇의 웹 채팅 클라이언트를 호스팅할 수 있는 도메인입니다.These are the domains that can host the bot's Web Chat client. 봇에 대한 Direct Line 구성 페이지의 목록과 일치해야 합니다.This should match the list in the Direct Line configuration page for your bot.

응답Response

요청이 성공하면 응답에는 하나의 대화에 유효한 token과 토큰이 만료될 때까지의 시간(초)을 나타내는 expires_in 값이 포함됩니다.If the request is successful, the response contains a token that is valid for one conversation and an expires_in value that indicates the number of seconds until the token expires. 토큰이 유효한 상태를 유지하려면 만료되기 전에 토큰을 새로 고쳐야 합니다.For the token to remain useful, you must refresh the token before it expires.

HTTP/1.1 200 OK
[other headers]
{
  "conversationId": "abc123",
  "token": "RCurR_XV9ZA.cwA.BKA.iaJrC8xpy8qbOF5xnR2vtCX7CZj0LdjAPGfiCpg4Fv0y8qbOF5xPGfiCpg4Fv0y8qqbOF5x8qbOF5xn",
  "expires_in": 1800
}

토큰 생성 및 대화 시작Generate Token versus Start Conversation

토큰 생성 작업(POST /v3/directline/tokens/generate)은 단일 대화에 액세스하는 데 사용할 수 있는 token을 반환한다는 점에서 대화 시작 작업(POST /v3/directline/conversations)과 비슷합니다.The Generate Token operation (POST /v3/directline/tokens/generate) is similar to the Start Conversation operation (POST /v3/directline/conversations) in that both operations return a token that can be used to access a single conversation. 그러나 대화 시작 작업과 달리, 토큰 생성 작업은 대화를 시작하지 않고, 봇에 연결하지 않고, 스트리밍 WebSocket URL을 만들지 않습니다.However, unlike the Start Conversation operation, the Generate Token operation does not start the conversation, does not contact the bot, and does not create a streaming WebSocket URL.

토큰을 클라이언트에 배포하고 대화를 시작하려는 경우 토큰 생성 작업을 사용합니다.If you plan to distribute the token to clients and want them to initiate the conversation, use the Generate Token operation. 대화를 즉시 시작하려는 경우 대신 대화 시작 작업을 사용합니다.If you intend to start the conversation immediately, use the Start Conversation operation instead.

직접 회선 토큰 새로 고침Refresh a Direct Line token

직접 회선 토큰은 만료되지만 않으면 횟수에 제한없이 새로 고칠 수 있습니다.A Direct Line token can be refreshed an unlimited amount of times, as long as it has not expired. 만료된 토큰은 새로 고칠 수 없습니다.An expired token cannot be refreshed. 직접 회선 토큰을 새로 고치려면 다음 요청을 실행합니다.To refresh a Direct Line token, issue this request:

POST https://directline.botframework.com/v3/directline/tokens/refresh
Authorization: Bearer TOKEN_TO_BE_REFRESHED

이 요청의 Authorization 헤더에서 TOKEN_TO_BE_REFRESHED 를 새로 고칠 직접 회선 토큰과 바꿉니다.In the Authorization header of this request, replace TOKEN_TO_BE_REFRESHED with the Direct Line token that you want to refresh.

다음 코드 조각은 토큰 새로 고침 요청 및 응답의 예제를 제공합니다.The following snippets provide an example of the Refresh Token request and response.

요청Request

POST https://directline.botframework.com/v3/directline/tokens/refresh
Authorization: Bearer CurR_XV9ZA.cwA.BKA.iaJrC8xpy8qbOF5xnR2vtCX7CZj0LdjAPGfiCpg4Fv0y8qbOF5xPGfiCpg4Fv0y8qqbOF5x8qbOF5xn

응답Response

요청이 성공하면 응답에는 이전 토큰과 동일한 대화에 대해 유효한 새로운 token과 토큰이 만료될 때까지의 시간(초)을 나타내는 expires_in 값이 포함됩니다.If the request is successful, the response contains a new token that is valid for the same conversation as the previous token and an expires_in value that indicates the number of seconds until the new token expires. 새 토큰이 유효한 상태를 유지하려면 만료되기 전에 토큰을 새로 고쳐야 합니다.For the new token to remain useful, you must refresh the token before it expires.

HTTP/1.1 200 OK
[other headers]
{
  "conversationId": "abc123",
  "token": "RCurR_XV9ZA.cwA.BKA.y8qbOF5xPGfiCpg4Fv0y8qqbOF5x8qbOF5xniaJrC8xpy8qbOF5xnR2vtCX7CZj0LdjAPGfiCpg4Fv0",
  "expires_in": 1800
}

Azure Bot Service 인증Azure Bot Service authentication

이 섹션에 제공된 정보는 Azure Bot Service 통해 봇에 인증 추가 문서를 기반으로 합니다.The information presented in this section is based on the Add authentication to your bot via Azure Bot Service article.

Azure Bot Service 인증 을 사용하면 Azure Active Directory, GitHub, Uber 등과 같은 다양한 ID 공급자에서 사용자를 인증하고 액세스 토큰 을 가져올 수 있습니다.Azure Bot Service authentication enables you to authenticate users to and get access tokens from a variety of identity providers such as Azure Active Directory, GitHub, Uber and so on. 또한 OAuth2 ID 공급자를 사용자 지정할 수 있도록 인증을 구성할 수 있습니다.You can also configure authentication for a custom OAuth2 identity provider. 이 모든 기능을 통해 지원되는 모든 ID 공급자 및 채널에서 작동하는 인증 코드의 한 부분 을 작성할 수 있습니다.All this enables you to write one piece of authentication code that works across all supported identity providers and channels. 이러한 기능을 활용하려면 다음 단계를 수행해야 합니다.To utilize these capabilities you need to perform the following steps:

  1. ID 공급자를 사용하여 애플리케이션 등록에 대한 세부 정보가 포함된 봇에서 정적으로 settings를 구성합니다.Statically configure settings on your bot that contains the details of your application registration with an identity provider.
  2. 이전 단계에서 제공한 애플리케이션 정보에 의해 지원되는 OAuthCard를 사용하여 사용자를로그인합니다.Use an OAuthCard, backed by the application information you supplied in the previous step, to sign-in a user.
  3. Azure Bot Service API 를 통해 액세스 토큰을 검색합니다.Retrieve access tokens through Azure Bot Service API.

보안 고려 사항Security considerations

웹 채팅Azure Bot Service 인증 을 사용할 때 고려해야 하는 몇 가지 중요한 보안 문제가 있습니다.When you use Azure Bot Service authentication with Web Chat there are some important security considerations you must keep in mind.

  1. 가장.Impersonation. 여기에서 가장이란 봇이 공격자를 다른 사람이라고 생각하도록 만드는 것을 의미합니다.Impersonation here means an attacker makes the bot thinks he is someone else. 웹 채팅에서 공격자는 웹 채팅 인스턴스에서 자신의 사용자 ID를 변경 하여 다른 사람으로 가장할 수 있습니다.In Web Chat, an attacker can impersonate someone else by changing the user ID of his Web Chat instance. 이를 방지하려면 봇 개발자가 사용자 ID를 추측할 수 없게 만드는 것이 좋습니다.To prevent this, it is recommend to bot developers to make the user ID unguessable.

    향상된 인증 옵션을 사용하도록 설정하면 Azure Bot Service가 사용자 ID 변경을 탐지하고 거부할 수 있습니다.If you enable enhanced authentication options, Azure Bot Service can further detect and reject any user ID change. Direct Line에서 봇으로 전송되는 메시지의 사용자 ID(Activity.From.Id)는 사용자가 웹 채팅을 초기화할 때 사용한 것과 항상 동일합니다.This means the user ID (Activity.From.Id) on messages from Direct Line to your bot will always be the same as the one you initialized the Web Chat with. 이 기능을 사용하려면 사용자 ID가 dl_로 시작해야 합니다.Note that this feature requires the user ID starts with dl_.

    참고

    토큰에 대한 비밀을 교환하는 동안 User.Id 가 제공되면 해당 User.Id 가 토큰에 포함됩니다.When a User.Id is provided while exchanging a secret for a token, that User.Id is embedded in the token. DirectLine은 봇에 전송된 메시지가 해당 ID를 작업의 From.Id 로 갖고 있는지 확인합니다. 클라이언트가 다른 From.Id 를 가진 DirectLine으로 메시지를 전송하는 경우 해당 메시지를 봇에 전달하기 전에 토큰의 ID 로 변경됩니다.DirectLine makes sure the messages sent to the bot have that id as the activity's From.Id. If a client sends a message to DirectLine having a different From.Id, it will be changed to the Id in the token before forwarding the message to the bot. 따라서 채널 비밀이 사용자 ID로 초기화된 후에는 다른 사용자 ID를 사용할 수 없습니다.So you cannot use another user id after a channel secret is initialized with a user id

  2. 사용자 ID.User identities. 다음 두 가지 사용자 ID를 처리하고 있다는 점을 알고 있어야 합니다.You must be aware that your are dealing with two user identities:

    1. 채널의 사용자 id입니다.The user's identity in a channel.
    2. 봇이 관심이 있는 id 공급자의 사용자 id입니다.The user's identity in an identity provider that the bot is interested in.

    사용자가 id 공급자 P에 로그인 하는 채널에서 사용자에 게 요청 하는 경우 로그인 프로세스는 사용자 A가 P에 로그인 하 고 있음을 확인 해야 합니다. 다른 사용자 B가 로그인 할 수 있는 경우 사용자 A는 bot을 통해 사용자 B의 리소스에 액세스할 수 있습니다.When a bot asks user A in a channel to sign-in to an identity provider P, the sign-in process must assure that user A is the one that signs into P. If another user B is allowed to sign-in, then user A would have access to user B's resource through the bot. 웹 채팅에는 다음에 설명된 대로 올바른 사용자가 로그인되도록 하는 두 가지 메커니즘이 있습니다.In Web Chat we have 2 mechanisms for ensuring the right user signed in as described next.

    1. 과거에는 로그인이 끝날 때 사용자에게 임의로 생성된 6자리 코드(즉, 매직 코드)가 제공되었습니다.At the end of sign-in, in the past, the user was presented with a randomly generated 6-digit code (aka magic code). 사용자는 로그인 프로세스를 완료하기 위해 로그인을 시작한 대화에서 이 코드를 입력해야 합니다.The user must type this code in the conversation that initiated the sign-in to complete the sign-in process. 이 메커니즘을 사용하면 잘못된 사용자 환경이 발생할 수 있습니다.This mechanism tends to result in a bad user experience. 또한 여전히 피싱 공격에 취약합니다.Additionally, it is still susceptible to phishing attacks. 악의적인 사용자는 다른 사용자에게 로그인하고 피싱을 통해 매직 코드를 얻을 수 있습니다.A malicious user can trick another user to sign-in and obtain the magic code through phishing.

    2. 이전 방법으로 인해 발생하는 문제때문에 Azure Bot Service에서 매직 코드의 필요성이 없어졌습니다.Because of the issues with the previous approach, Azure Bot Service removed the need for the magic code. Azure Bot Service는 로그인 프로세스가 웹 채팅 자체와 동일한 브라우저 세션 에서 완료되도록 보장할 수 있습니다.Azure Bot Service guarantees that the sign-in process can only be completed in the same browser session as the Web Chat itself. 이 보호를 사용 하도록 설정 하려면 bot developer에서 봇의 웹 채팅 클라이언트를 호스트할 수 있는 신뢰할 수 있는 도메인 목록을 포함 하는 직접 회선 토큰 을 사용 하 여 웹 채팅을 시작 해야 합니다.To enable this protection, as a bot developer, you must start Web Chat with a Direct Line token that contains a list of trusted domains that can host the bot's Web Chat client. 이전에는 문서화되지 않은 선택적 매개 변수를 Direct Line 토큰 API에 전달해야만 이 토큰을 가져올 수 있었습니다.Before, you could only obtain this token by passing an undocumented optional parameter to the Direct Line token API. 현재 향상된 인증 옵션을 사용하면 Direct Line 구성 페이지에서 트러스트된 도메인(원본) 목록을 정적으로 지정할 수 있습니다.Now, with enhanced authentication options, you can statically specify the trusted domain (origin) list in the Direct Line configuration page.

    Azure Bot Service를 통해 봇에 인증 추가도 참조하세요.See also Add authentication to your bot via Azure Bot Service.

코드 예제Code examples

다음 .NET 컨트롤러는 향상된 인증 옵션을 사용하여 작동하며 Direct Line 토큰과 사용자 ID를 반환합니다.The following .NET controller works with enhanced authentication options enabled and returns a Direct Line Token and user ID.

public class HomeController : Controller
{
    public async Task<ActionResult> Index()
    {
        var secret = GetSecret();

        HttpClient client = new HttpClient();

        HttpRequestMessage request = new HttpRequestMessage(
            HttpMethod.Post,
            $"https://directline.botframework.com/v3/directline/tokens/generate");

        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", secret);

        var userId = $"dl_{Guid.NewGuid()}";

        request.Content = new StringContent(
            JsonConvert.SerializeObject(
                new { User = new { Id = userId } }),
                Encoding.UTF8,
                "application/json");

        var response = await client.SendAsync(request);
        string token = String.Empty;

        if (response.IsSuccessStatusCode)
        {
            var body = await response.Content.ReadAsStringAsync();
            token = JsonConvert.DeserializeObject<DirectLineToken>(body).token;
        }

        var config = new ChatConfig()
        {
            Token = token,
            UserId = userId
        };

        return View(config);
    }
}

public class DirectLineToken
{
    public string conversationId { get; set; }
    public string token { get; set; }
    public int expires_in { get; set; }
}
public class ChatConfig
{
    public string Token { get; set; }
    public string UserId { get; set; }
}

다음 JavaScript 컨트롤러는 향상된 인증 옵션을 사용하여 작동하며 Direct Line 토큰과 사용자 ID를 반환합니다.The following JavaScript controller works with enhanced authentication options enabled and returns a Direct Line Token and user ID.

var router = express.Router(); // get an instance of the express Router

// Get a directline configuration (accessed at GET /api/config)
const userId = "dl_" + createUniqueId();

router.get('/config', function(req, res) {
    const options = {
        method: 'POST',
        uri: 'https://directline.botframework.com/v3/directline/tokens/generate',
        headers: {
            'Authorization': 'Bearer ' + secret
        },
        json: {
            User: { Id: userId }
        }
    };

    request.post(options, (error, response, body) => {
        if (!error && response.statusCode < 300) {
            res.json({
                    token: body.token,
                    userId: userId
                });
        }
        else {
            res.status(500).send('Call to retrieve token from Direct Line failed');
        }
    });
});

추가 리소스Additional resources