다음을 통해 공유


Azure Cosmos DB 문서 데이터베이스를 사용하여 사용자 인증 및 Xamarin.Forms

Azure Cosmos DB 문서 데이터베이스는 여러 서버 및 파티션에 걸쳐 있을 수 있는 분할된 컬렉션을 지원하면서 무제한 스토리지 및 처리량을 지원합니다. 이 문서에서는 사용자가 애플리케이션에서 자신의 문서에만 액세스할 수 있도록 액세스 제어를 분할된 컬렉션과 결합하는 Xamarin.Forms 방법을 설명합니다.

개요

분할된 컬렉션을 만들 때 파티션 키를 지정해야 하며 파티션 키가 같은 문서는 동일한 파티션에 저장됩니다. 따라서 사용자의 ID를 파티션 키로 지정하면 해당 사용자에 대한 문서만 저장하는 분할된 컬렉션이 생성됩니다. 이렇게 하면 사용자 및 항목 수가 증가함에 따라 Azure Cosmos DB 문서 데이터베이스의 크기가 조정됩니다.

모든 컬렉션에 대한 액세스 권한을 부여해야 하며 NoSQL용 Azure Cosmos DB 액세스 제어 모델은 두 가지 유형의 액세스 구문을 정의합니다.

  • 마스터 키를 사용하면 Azure Cosmos DB 계정 내의 모든 리소스에 대한 모든 관리 액세스가 가능하며 Azure Cosmos DB 계정이 만들어지면 생성됩니다.
  • 리소스 토큰은 데이터베이스 사용자와 컬렉션 또는 문서와 같은 특정 Azure Cosmos DB 리소스에 대해 사용자가 가진 권한 간의 관계를 캡처합니다.

마스터 키를 노출하면 Azure Cosmos DB 계정이 악의적이거나 부주의한 사용 가능성이 열립니다. 그러나 Azure Cosmos DB 리소스 토큰은 클라이언트가 부여된 권한에 따라 Azure Cosmos DB 계정에서 특정 리소스를 읽고 쓰고 삭제할 수 있도록 하는 안전한 메커니즘을 제공합니다.

모바일 애플리케이션에 리소스 토큰을 요청, 생성 및 전달하는 일반적인 방법은 리소스 토큰 브로커를 사용하는 것입니다. 다음 다이어그램에서는 샘플 애플리케이션이 리소스 토큰 브로커를 사용하여 문서 데이터베이스 데이터에 대한 액세스를 관리하는 방법에 대한 개략적인 개요를 보여 있습니다.

문서 데이터베이스 인증 프로세스

리소스 토큰 브로커는 Azure Cosmos DB 계정의 마스터 키를 소유하는 Azure 앱 Service에서 호스트되는 중간 계층 Web API 서비스입니다. 샘플 애플리케이션은 다음과 같이 리소스 토큰 브로커를 사용하여 문서 데이터베이스 데이터에 대한 액세스를 관리합니다.

  1. 로그인할 때 애플리케이션은 Xamarin.Forms Azure 앱 서비스에 연결하여 인증 흐름을 시작합니다.
  2. Azure 앱 Service는 Facebook을 사용하여 OAuth 인증 흐름을 수행합니다. 인증 흐름이 완료되면 애플리케이션은 Xamarin.Forms 액세스 토큰을 받습니다.
  3. 애플리케이션은 Xamarin.Forms 액세스 토큰을 사용하여 리소스 토큰 브로커에서 리소스 토큰을 요청합니다.
  4. 리소스 토큰 브로커는 액세스 토큰을 사용하여 Facebook에서 사용자의 ID를 요청합니다. 그런 다음 사용자의 ID를 사용하여 인증된 사용자의 분할된 컬렉션에 대한 읽기/쓰기 액세스 권한을 부여하는 데 사용되는 Azure Cosmos DB에서 리소스 토큰을 요청합니다.
  5. 애플리케이션은 Xamarin.Forms 리소스 토큰을 사용하여 리소스 토큰에 정의된 권한으로 Azure Cosmos DB 리소스에 직접 액세스합니다.

참고 항목

리소스 토큰이 만료되면 후속 문서 데이터베이스 요청은 401 권한 없는 예외를 받습니다. 이 시점에서 Xamarin.Forms 애플리케이션은 ID를 다시 설정하고 새 리소스 토큰을 요청해야 합니다.

Azure Cosmos DB 분할에 대한 자세한 내용은 Azure Cosmos DB에서 분할 및 스케일링하는 방법을 참조하세요. Azure Cosmos DB 액세스 제어에 대한 자세한 내용은 Azure Cosmos DB 데이터에 대한 액세스 보안 및 NoSQL용 Azure Cosmos DB의 액세스 제어를 참조하세요.

설정

리소스 토큰 브로커를 애플리케이션에 Xamarin.Forms 통합하는 프로세스는 다음과 같습니다.

  1. 액세스 제어를 사용할 Azure Cosmos DB 계정을 만듭니다. 자세한 내용은 Azure Cosmos DB 구성을 참조 하세요.
  2. 리소스 토큰 브로커를 호스트하는 Azure 앱 서비스를 만듭니다. 자세한 내용은 Azure 앱 서비스 구성을 참조하세요.
  3. 인증을 수행하는 Facebook 앱을 만듭니다. 자세한 내용은 Facebook 앱 구성을 참조 하세요.
  4. Facebook에서 간편한 인증을 수행하도록 Azure 앱 서비스를 구성합니다. 자세한 내용은 Azure 앱 서비스 인증 구성을 참조하세요.
  5. Xamarin.Forms Azure 앱 Service 및 Azure Cosmos DB와 통신하도록 샘플 애플리케이션을 구성합니다. 자세한 내용은 애플리케이션 구성을 참조 Xamarin.Forms 하세요.

참고 항목

Azure 구독이 아직 없는 경우 시작하기 전에 체험 계정을 만듭니다.

Azure Cosmos DB 구성

액세스 제어를 사용하는 Azure Cosmos DB 계정을 만드는 프로세스는 다음과 같습니다.

  1. Azure Cosmos DB 계정을 만듭니다. 자세한 내용은 Azure Cosmos DB 계정 만들기를 참조 하세요.
  2. Azure Cosmos DB 계정에서 의 /userid파티션 키를 지정하는 새 UserItems컬렉션을 만듭니다.

Azure 앱 서비스 구성

Azure 앱 Service에서 리소스 토큰 브로커를 호스팅하는 프로세스는 다음과 같습니다.

  1. Azure Portal에서 새 App Service 웹앱을 만듭니다. 자세한 내용은 App Service Environment에서 웹앱 만들기를 참조 하세요.

  2. Azure Portal에서 웹앱에 대한 앱 설정 블레이드를 열고 다음 설정을 추가합니다.

    • accountUrl – 값은 Azure Cosmos DB 계정의 키 블레이드에서 Azure Cosmos DB 계정 URL이어야 합니다.
    • accountKey – 값은 Azure Cosmos DB 계정의 키 블레이드에서 Azure Cosmos DB 마스터 키(기본 또는 보조)여야 합니다.
    • databaseId – 값은 Azure Cosmos DB 데이터베이스의 이름이어야 합니다.
    • collectionId – 값은 Azure Cosmos DB 컬렉션의 이름이어야 합니다(이 경우 UserItems).
    • hostUrl – 값은 App Service 계정의 개요 블레이드에서 웹앱의 URL이어야 합니다.

    다음 스크린샷은 이 구성을 보여 줍니다.

    App Service Web App 설정

  3. 리소스 토큰 브로커 솔루션을 Azure 앱 Service 웹앱에 게시합니다.

Facebook 앱 구성

인증을 수행하기 위해 Facebook 앱을 만드는 프로세스는 다음과 같습니다.

  1. Facebook 앱을 만듭니다. 자세한 내용은 Facebook 개발자 센터에서 앱 등록 및 구성을 참조하세요.
  2. Facebook 로그인 제품을 앱에 추가합니다. 자세한 내용은 Facebook 개발자 센터의 앱 또는 웹 사이트에 Facebook 로그인 추가를 참조하세요.
  3. 다음과 같이 Facebook 로그인을 구성합니다.
    • 클라이언트 OAuth 로그인을 사용하도록 설정합니다.
    • 웹 OAuth 로그인을 사용하도록 설정합니다.
    • 추가된 App Service 웹앱의 URI에 유효한 OAuth 리디렉션 URI를 /.auth/login/facebook/callback 설정합니다.

다음 스크린샷은 이 구성을 보여 줍니다.

Facebook 로그인 OAuth 설정

자세한 내용은 Facebook에 애플리케이션 등록을 참조하세요.

Azure 앱 서비스 인증 구성

App Service 간편한 인증을 구성하는 프로세스는 다음과 같습니다.

  1. Azure Portal에서 App Service 웹앱으로 이동합니다.

  2. Azure Portal에서 인증/권한 부여 블레이드를 열고 다음 구성을 수행합니다.

    • App Service 인증을 설정해야 합니다.
    • 요청이 인증되지 않은 경우 수행할 작업은 Facebook 로그인으로 설정해야 합니다.

    다음 스크린샷은 이 구성을 보여 줍니다.

    App Service Web App 인증 설정

인증 흐름을 사용하도록 Facebook 앱과 통신하도록 App Service 웹앱도 구성해야 합니다. Facebook ID 공급자를 선택하고 Facebook 개발자 센터의 Facebook 앱 설정에서 앱 ID앱 비밀 값을 입력하여 이 작업을 수행할 수 있습니다. 자세한 내용은 애플리케이션에 Facebook 정보 추가를 참조하세요.

Xamarin.Forms 애플리케이션 구성

샘플 애플리케이션을 Xamarin.Forms 구성하는 프로세스는 다음과 같습니다.

  1. Xamarin.Forms 솔루션을 엽니다.
  2. 다음 상수의 값을 열고 Constants.cs 업데이트합니다.
    • EndpointUri – 값은 Azure Cosmos DB 계정의 키 블레이드에서 Azure Cosmos DB 계정 URL이어야 합니다.
    • DatabaseName – 값은 문서 데이터베이스의 이름이어야 합니다.
    • CollectionName – 값은 문서 데이터베이스 컬렉션의 이름이어야 합니다(이 경우 UserItems).
    • ResourceTokenBrokerUrl – 값은 App Service 계정의 개요 블레이드에서 리소스 토큰 브로커 웹앱의 URL이어야 합니다.

로그인 시작

샘플 애플리케이션은 다음 예제 코드에 설명된 대로 브라우저를 ID 공급자 URL로 리디렉션하여 로그인 프로세스를 시작합니다.

var auth = new Xamarin.Auth.WebRedirectAuthenticator(
  new Uri(Constants.ResourceTokenBrokerUrl + "/.auth/login/facebook"),
  new Uri(Constants.ResourceTokenBrokerUrl + "/.auth/login/done"));

이로 인해 Azure 앱 서비스와 Facebook 간에 OAuth 인증 흐름이 시작되고 Facebook 로그인 페이지가 표시됩니다.

Facebook 로그인

iOS에서 취소 단추를 누르거나 Android에서 뒤로 단추를 눌러 로그인을 취소할 수 있습니다. 이 경우 사용자가 인증되지 않은 상태로 다시 기본 ID 공급자 사용자 인터페이스가 화면에서 제거됩니다.

리소스 토큰 가져오기

인증에 WebRedirectAuthenticator.Completed 성공하면 이벤트가 발생합니다. 다음 코드 예제에서는 이 이벤트를 처리하는 방법을 보여 줍니다.

auth.Completed += async (sender, e) =>
{
  if (e.IsAuthenticated && e.Account.Properties.ContainsKey("token"))
  {
    var easyAuthResponseJson = JsonConvert.DeserializeObject<JObject>(e.Account.Properties["token"]);
    var easyAuthToken = easyAuthResponseJson.GetValue("authenticationToken").ToString();

    // Call the ResourceBroker to get the resource token
    using (var httpClient = new HttpClient())
    {
      httpClient.DefaultRequestHeaders.Add("x-zumo-auth", easyAuthToken);
      var response = await httpClient.GetAsync(Constants.ResourceTokenBrokerUrl + "/api/resourcetoken/");
      var jsonString = await response.Content.ReadAsStringAsync();
      var tokenJson = JsonConvert.DeserializeObject<JObject>(jsonString);
      resourceToken = tokenJson.GetValue("token").ToString();
      UserId = tokenJson.GetValue("userid").ToString();

      if (!string.IsNullOrWhiteSpace(resourceToken))
      {
        client = new DocumentClient(new Uri(Constants.EndpointUri), resourceToken);
        ...
      }
      ...
    }
  }
};

성공적인 인증의 결과는 사용 가능한 AuthenticatorCompletedEventArgs.Account 속성인 액세스 토큰입니다. 액세스 토큰은 추출되어 리소스 토큰 브로커의 resourcetoken API에 대한 GET 요청에 사용됩니다.

API는 resourcetoken 액세스 토큰을 사용하여 Facebook에서 사용자의 ID를 요청합니다. 이 ID는 Azure Cosmos DB에서 리소스 토큰을 요청하는 데 사용됩니다. 문서 데이터베이스에 있는 사용자에 대한 유효한 사용 권한 문서가 이미 있는 경우 해당 문서가 검색되고 리소스 토큰이 포함된 JSON 문서가 애플리케이션에 Xamarin.Forms 반환됩니다. 사용자에게 유효한 사용 권한 문서가 없으면 사용자 및 권한이 문서 데이터베이스에 생성되고 리소스 토큰이 사용 권한 문서에서 추출되어 JSON 문서의 애플리케이션으로 반환 Xamarin.Forms 됩니다.

참고 항목

문서 데이터베이스 사용자는 문서 데이터베이스와 연결된 리소스이며 각 데이터베이스에는 0명 이상의 사용자가 포함될 수 있습니다. 문서 데이터베이스 사용 권한은 문서 데이터베이스 사용자와 연결된 리소스이며 각 사용자에게는 0개 이상의 권한이 포함될 수 있습니다. 권한 리소스는 문서와 같은 리소스에 액세스하려고 할 때 사용자에게 필요한 보안 토큰에 대한 액세스를 제공합니다.

API가 resourcetoken 성공적으로 완료되면 리소스 토큰이 포함된 JSON 문서와 함께 응답에 HTTP 상태 코드 200(확인)을 보냅니다. 다음 JSON 데이터는 일반적인 성공적인 응답 메시지를 보여줍니다.

{
  "id": "John Smithpermission",
  "token": "type=resource&ver=1&sig=zx6k2zzxqktzvuzuku4b7y==;a74aukk99qtwk8v5rxfrfz7ay7zzqfkbfkremrwtaapvavw2mrvia4umbi/7iiwkrrq+buqqrzkaq4pp15y6bki1u//zf7p9x/aefbvqvq3tjjqiffurfx+vexa1xarxkkv9rbua9ypfzr47xpp5vmxuvzbekkwq6txme0xxxbjhzaxbkvzaji+iru3xqjp05amvq1r1q2k+qrarurhmjzah/ha0evixazkve2xk1zu9u/jpyf1xrwbkxqpzebvqwma+hyyaazemr6qx9uz9be==;",
  "expires": 4035948,
  "userid": "John Smith"
}

WebRedirectAuthenticator.Completed 이벤트 처리기는 API에서 resourcetoken 응답을 읽고 리소스 토큰 및 사용자 ID를 추출합니다. 그런 다음 리소스 토큰이 생성자에 인수 DocumentClient 로 전달되어 Azure Cosmos DB에 액세스하는 데 사용되는 엔드포인트, 자격 증명 및 연결 정책을 캡슐화하고 Azure Cosmos DB에 대한 요청을 구성하고 실행하는 데 사용됩니다. 리소스 토큰은 리소스에 직접 액세스하기 위해 각 요청과 함께 전송되며 인증된 사용자의 분할된 컬렉션에 대한 읽기/쓰기 액세스 권한이 부여됨을 나타냅니다.

문서 검색

인증된 사용자에만 속하는 문서 검색은 사용자의 ID를 파티션 키로 포함하는 문서 쿼리를 만들어 수행할 수 있으며 다음 코드 예제에 설명되어 있습니다.

var query = client.CreateDocumentQuery<TodoItem>(collectionLink,
                        new FeedOptions
                        {
                          MaxItemCount = -1,
                          PartitionKey = new PartitionKey(UserId)
                        })
          .Where(item => !item.Id.Contains("permission"))
          .AsDocumentQuery();
while (query.HasMoreResults)
{
  Items.AddRange(await query.ExecuteNextAsync<TodoItem>());
}

쿼리는 지정된 컬렉션에서 인증된 사용자에 속한 모든 문서를 비동기적으로 검색하여 표시할 컬렉션에 List<TodoItem> 배치합니다.

이 메서드는 CreateDocumentQuery<T> 문서에 대해 쿼리해야 하는 컬렉션과 개체를 나타내는 인수를 FeedOptions 지정 Uri 합니다. 개체는 FeedOptions 쿼리에서 무제한의 항목을 반환할 수 있도록 지정하고 사용자의 ID를 파티션 키로 지정합니다. 이렇게 하면 사용자의 분할된 컬렉션에 있는 문서만 결과에 반환됩니다.

참고 항목

리소스 토큰 브로커에서 만든 권한 문서는 애플리케이션에서 만든 문서와 동일한 문서 컬렉션에 Xamarin.Forms 저장됩니다. 따라서 문서 쿼리에는 문서 컬렉션에 대한 쿼리에 필터링 조건자를 적용하는 절이 포함 Where 됩니다. 이 절은 사용 권한 문서가 문서 컬렉션에서 반환되지 않도록 합니다.

문서 컬렉션에서 문서를 검색하는 방법에 대한 자세한 내용은 문서 컬렉션 문서 검색을 참조 하세요.

문서 삽입

문서 컬렉션 TodoItem.UserId 에 문서를 삽입하기 전에 다음 코드 예제와 같이 파티션 키로 사용되는 값으로 속성을 업데이트해야 합니다.

item.UserId = UserId;
await client.CreateDocumentAsync(collectionLink, item);

이렇게 하면 문서가 사용자의 분할된 컬렉션에 삽입됩니다.

문서 컬렉션에 문서를 삽입하는 방법에 대한 자세한 내용은 문서 컬렉션에 문서 삽입을 참조 하세요.

문서 삭제

다음 코드 예제와 같이 분할된 컬렉션에서 문서를 삭제할 때 파티션 키 값을 지정해야 합니다.

await client.DeleteDocumentAsync(UriFactory.CreateDocumentUri(Constants.DatabaseName, Constants.CollectionName, id),
                 new RequestOptions
                 {
                   PartitionKey = new PartitionKey(UserId)
                 });

이렇게 하면 Azure Cosmos DB에서 문서를 삭제할 분할된 컬렉션을 알 수 있습니다.

문서 컬렉션에서 문서를 삭제하는 방법에 대한 자세한 내용은 문서 컬렉션에서 문서 삭제를 참조 하세요.

요약

이 문서에서는 사용자가 애플리케이션에서 자신의 문서 데이터베이스 문서에만 액세스할 수 있도록 액세스 제어를 분할된 컬렉션과 결합하는 Xamarin.Forms 방법을 설명했습니다. 사용자의 ID를 파티션 키로 지정하면 분할된 컬렉션에서 해당 사용자에 대한 문서만 저장할 수 있습니다.