다음을 통해 공유


최전방 직원이 근무하지 않는 경우 Microsoft Teams에 대한 액세스 제한

개요

근무 시간은 관리자가 Android 및 iOS 모바일 디바이스의 교대 근무자를 위해 Microsoft Teams에 대한 액세스를 제한할 수 있는 기능입니다. 이러한 컨트롤은 최전방 작업자를 위한 BYOD(Bring Your Own Device) 또는 회사 소유 전용 디바이스 시나리오를 위해 설계되었습니다. 최전방 디바이스 시나리오에 대해 자세히 알아보세요.

이 기능을 사용하면 교대 근무를 하지 않는 최전방 직원이 Teams를 열 때 Teams에 대한 액세스를 차단하거나 경고 메시지를 표시할 수 있습니다. 다음과 같은 경우 최전방 인력의 근무 시간을 사용하도록 설정하는 것이 좋습니다.

  • 일선 근로자가 작업 앱에 액세스하는 경우 근무 시간 외의 임금을 요구하는 것에 대해 우려하고 있습니다.
  • 현지 법률 및 규정에 따라 직원이 근무하지 않는 경우 회사 앱에 대한 액세스를 제한해야 합니다.

작동 방법

최전방 작업자가 교대 근무를 하고 Teams를 열면 앱은 작업자가 교대 근무 중인지 여부를 확인합니다.

  • 작업자가 교대 근무 중인 경우 Teams에 액세스할 수 있습니다.
  • Teams가 열려 있을 때 작업자가 교대 근무를 중단하면 작업자가 블록 또는 경고 화면을 볼 수 있습니다.
    • 블록 화면을 구성한 경우 작업자는 교대 근무로 전환될 때까지 Teams에 액세스할 수 없습니다.
    • 경고 화면을 구성한 경우 작업자는 경고 화면을 해제하고 재량에 따라 Teams를 사용할지 여부를 선택할 수 있습니다.
  • 작업자가 클록아웃하는 동안 Teams를 사용하는 경우 작업자는 시계 종료 후 앱에 대한 블록 또는 경고 화면을 볼 수 있습니다.

차단 액세스 화면 및 경고 화면의 스크린샷

근무 시간과 함께 작업자가 교대 근무 중일 때 Teams 알림을 자동으로 음소거하도록 조용한 시간을 설정하는 것이 좋습니다.

작업 시간 설정

다음 단계에 따라 최전방에서 근무 시간을 사용하도록 설정합니다.

Android 및 iOS에 대한 앱 보호 정책 구성

Microsoft Intune 앱 보호 정책을 사용하여 Android 및 iOS 디바이스에서 Teams에 대한 액세스를 차단하거나 경고하는 작업 시간을 구성합니다. 정책 설정에 대한 자세한 내용은 다음을 참조하세요.

WFM(인력 관리 시스템)을 workingTimeSchedule API에 연결

애플리케이션 만들기

  1. workingTimeSchedule Graph API 대한 Microsoft Entra 애플리케이션을 만듭니다.

    애플리케이션을 등록할 때 테넌트 사용자만 애플리케이션을 사용할 수 있도록 이 조직 디렉터리에서 계정만(단일 테넌트) 옵션을 선택해야 합니다. 자세한 내용은 Microsoft ID 플랫폼 애플리케이션 등록을 참조하세요.

  2. 필요한 Schedule-WorkingTime.ReadWrite.Allscope 를 사용하여 Graph API 호출하기 위한 숨겨진 애플리케이션 권한을 추가합니다.

    1. Azure Portal 애플리케이션에 로그인합니다.

    2. 매니페스트 탭으로 이동합니다. 애플리케이션의 전체 정의가 포함된 JSON이 표시됩니다.

    3. 매니페스트의 끝에 속성을 추가합니다 requiredResourceAccess .

      이 속성은 애플리케이션에 액세스해야 하는 사용 권한 집합을 지정합니다. 즉, 애플리케이션에서 호출할 수 있는 모든 API를 포함합니다. 이 속성이 매니페스트에 이미 있는 경우 API에 이미 부여된 몇 가지 권한이 있습니다.

    4. 배열 내에서 ID가 requiredResourceAccess00000003-0000-0000-0000-c000-0000000000000000 개체를 추가하여 Graph 애플리케이션의 권한을 지정합니다.

      배열 내에 requiredResourceAccess 동일한 ID를 가진 개체가 이미 있는 경우 배열 내부에 resourceAccess 다음만 추가하면 됩니다.

      • 새 숨겨진 권한의 ID가 인 개체입니다 0b21c159-dbf4-4dbb-a6f6-490e412c716e.
      • 사용 권한의 유형입니다. 이 경우 입니다 Role.

      매니페스트의 끝 모양에 대한 예는 다음과 같습니다.

      {
        ...
        "preAuthorizedApplications": [],
        "publisherDomain": "microsoft.onmicrosoft.com",
        "replyUrlsWithType": [
          {
            "url": "https://localhost:44321/signin-oidc",
            "type": "Web"
          },
          {
            "url": "https://localhost:44321/",
            "type": "Web"
          }
        ],
        "requiredResourceAccess": [
          {
            "resourceAppId": "00000003-0000-0000-c000-000000000000",
            "resourceAccess": [
              {
                "id": "0b21c159-dbf4-4dbb-a6f6-490e412c716e",
                "type": "Role"
              }
            ]
          }
        ],
        "samlMetadataUrl": null,
        "signInUrl": null,
        "signInAudience": "AzureADMyOrg",
        "tags": [],
        "tokenEncryptionKeyId": null
      }
      
    5. 변경 내용을 저장합니다.

이 단계를 수행하려면 테넌트 관리자여야 합니다.

  1. 브라우저에서 ; response_type=code&scope=로https://graph.microsoft.com/.default 이동합니다https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={ClientAppId}&.
  2. URL에서 를 앱 ID로 바꿉 ClientAppId 니다.
  3. 동의 대화 상자에서 동의 를 선택하여 애플리케이션에 대한 새 숨겨진 권한에 테넌트 전체 관리자 동의를 부여합니다.

애플리케이션에서 Graph 호출

다음은 C#의 예제 코드를 사용하여 애플리케이션에서 Graph 엔드포인트를 호출하는 방법입니다.

  1. .NET 6 또는 .NET 7 SDK를 사용하여 새 콘솔 프로젝트를 만듭니다.

  2. Microsoft.Identity.Client NuGet 패키지를 설치합니다.

  3. program.cs 파일을 열고 다음 예제 코드를 복사하여 붙여넣습니다.

        using System.Text;
      using Microsoft.Identity.Client;
      var userId = "928bf23a-81e8-47c9-ad54-2c0206248afe";
      var path = Path.Combine(Path.GetTempPath(),
      "workingTimeTokenGenerator.txt");
    
      string? accessToken;
      if (!File.Exists(path) || (DateTime.UtcNow - new
      FileInfo(path).LastWriteTimeUtc).TotalMinutes > 59)
      {
        var clientId = "00001111-aaaa-2222-bbbb-3333cccc4444";
        var clientSecret = "Aa1Bb~2Cc3.-Dd4Ee5Ff6Gg7Hh8Ii9_Jj0Kk1Ll2";
        var tenantId = "cad3e174-69d3-4707-abd2-f527f45c367a";
        var scopes = new string[] { "00000003-0000-0000-c000-000000000000/.default" };
    
        var app = ConfidentialClientApplicationBuilder.Create(clientId)
          .WithClientSecret(clientSecret)
          .Build();
    
        var result = await app.AcquireTokenForClient(scopes)
          .WithAuthority(AzureCloudInstance.AzurePublic, tenantId)
          .ExecuteAsync();
    
        accessToken = result.AccessToken;
        File.WriteAllText(path, accessToken);
      }
      else
      {
        accessToken = File.ReadAllText(path);
      }
    
      int number;
    
      while (true)
      {
        Console.WriteLine("Press 1 for startWorkingTime, 2 for endWorkingTime.");
        var choice = Console.ReadLine();
        if (!Int32.TryParse(choice, out number) || !new[] { 1, 2}.Contains(number))
        {
          Console.WriteLine("Out-of-range election.");
          continue;
        }
    
        break;
      }
    
      Console.WriteLine("Performing request...");
      var httpClient = new HttpClient();
      var message = new HttpRequestMessage
      {
        Method = HttpMethod.Post,
        RequestUri = new
      Uri($"https://graph.microsoft.com/beta/users/{userId}/solutions/schedule/{(number == 1 ? "startWorkingTime" : "endWorkingTime")}")
      };
      message.Headers.Add("Authorization", $"Bearer {accessToken}");
      message.Content = new StringContent("", Encoding.UTF8,
      "application/json");
      var response = await httpClient.SendAsync(message);
      if (!response.IsSuccessStatusCode)
      {
        string? content = null;
        try
        {
          content = await response.Content?.ReadAsStringAsync();
        }
        catch
        {
        }
    
        Console.WriteLine($"Graph returned a non success status code: 
      {response.StatusCode}. Reason phrase: {response.ReasonPhrase}." +
          (content is null ? "Unable to get the response body." :
      $"Content: {content}"));
      }
      else
      {
        Console.WriteLine($"Graph returned a success status code: 
      {response.StatusCode}.");
      }
    
      Console.WriteLine("Press any key to exit.");
      _ = Console.ReadKey();
    
  4. 코드에서 다음을 변경합니다.

    • tenantId: 를 테넌트 ID로 대체합니다.
    • clientId: 을 애플리케이션의 ID로 바꿉니다.
    • clientSecret: 애플리케이션의 인증 섹션에서 클라이언트 암호를 추가해야 합니다. 보안 인증서를 사용하고 그에 따라 코드를 변경하도록 선택할 수도 있습니다.
    • userId: 를 inWorkingTime 또는 outOfWorkingTime 정책을 적용할 사용자로 바꿉니다.

조용한 시간 설정

이 단계는 선택 사항이지만 권장됩니다.

근무 시간 외 최전방 작업자에 대한 Teams 알림을 자동으로 음소거하도록 Intune 자동 시간 정책을 구성합니다. 조용한 시간 정책을 만드는 방법에 대해 자세히 알아봅니다.

질문과 대답

이 기능을 활용하려면 Teams에서 Shifts 앱을 사용해야 하나요?

아니요, 이 기능은 WFM 클록 인/아웃 신호를 사용합니다.

시계가 없는 경우 작업 시간을 사용할 수 있나요?

아니요, 이 기능을 사용하려면 클록 인/아웃 신호가 필요합니다.