認証の基本Authentication basics

認証とはWhat is authentication

この記事では、保護された Web アプリ、Web API、または保護された Web API を呼び出すアプリを作成するために理解する必要がある認証の概念の多くについて説明します。This article covers many of the authentication concepts you'll need to understand to create protected web apps, web APIs, or apps calling protected Web APIs.

認証は、ユーザーが身元を証明するプロセスです。Authentication is the process of proving you are who you say you are. 認証は AuthN と短縮される場合があります。Authentication is sometimes shortened to AuthN.

承認は、認証された利用者に対し、何かを実行する権限を付与する行為です。Authorization is the act of granting an authenticated party permission to do something. アクセスが許可されるデータと、そのデータで実行できる操作を指定します。It specifies what data you're allowed to access and what you can do with that data. 承認は AuthZ と短縮される場合があります。Authorization is sometimes shortened to AuthZ.

それぞれ独自のユーザー名とパスワードの情報を保持するアプリを作成する (これにより、複数のアプリにまたがってユーザーを追加または削除する必要があるときに管理上の負担が大きくなります) 代わりに、アプリで、一元化された ID プロバイダーに責任を委任することができます。Instead of creating apps that each maintain their own username and password information, which incurs a high administrative burden when you need to add or remove users across multiple apps, apps can delegate that responsibility to a centralized identity provider.

Azure Active Directory (Azure AD) は、クラウド内の一元化された ID プロバイダーです。Azure Active Directory (Azure AD) is a centralized identity provider in the cloud. 認証と承認を委任することにより、ユーザーが特定の場所にいることを要求する条件付きアクセス ポリシー、多要素認証の使用のほか、ユーザーが 1 回サインインすると、同じ一元化されたディレクトリを共有するすべての Web アプリに自動的にサインインできるようにするなどのシナリオを実現できます。Delegating authentication and authorization to it enables scenarios such as Conditional Access policies that require a user to be in a specific location, the use of multi-factor authentication, as well as enabling a user to sign in once and then be automatically signed in to all of the web apps that share the same centralized directory. この機能は、シングル サインオン (SSO) と呼ばれます。This capability is referred to as Single Sign On (SSO).

一元化された ID プロバイダーは、ユーザーが世界中にいて、企業のネットワークから必ずしもサインインするわけではないアプリにとってさらに重要です。A centralized identity provider is even more important for apps that have users located around the globe that don't necessarily sign in from the enterprise's network. Azure AD では、ユーザーが認証され、アクセス トークンが提供されます。Azure AD authenticates users and provides access tokens. アクセス トークンは、承認サーバーから発行されるセキュリティ トークンです。An access token is a security token that is issued by an authorization server. トークンの対象となるユーザーとアプリに関する情報が含まれ、Web API やその他の保護されたリソースにアクセスするために使用できます。It contains information about the user and the app for which the token is intended, which can be used to access Web APIs and other protected resources.

Microsoft ID プラットフォームでは、Identity as a Service を提供しています。コーディングをすばやく開始できるように、OAuth 2.0 や OpenID Connect などの業界標準プロトコルをサポートし、さまざまなプラットフォーム向けのオープン ソース ライブラリを提供して、アプリケーション開発者が簡単に認証できるようにしています。The Microsoft identity platform simplifies authentication for application developers by providing identity as a service, with support for industry-standard protocols such as OAuth 2.0 and OpenID Connect, as well as open-source libraries for different platforms to help you start coding quickly. これにより、開発者はすべての Microsoft ID にサインインし、Microsoft Graph、その他の Microsoft API、または開発者が作成した API を呼び出すトークンを取得することができます。It allows developers to build applications that sign in all Microsoft identities, get tokens to call Microsoft Graph, other Microsoft APIs, or APIs that developers have built. 詳細については、「Microsoft ID プラットフォームの進化」を参照してください。For more information, see Evolution of Microsoft identity platform.

テナントTenants

クラウド ID プロバイダーでは、数多くの組織にサービスが提供されます。A cloud identity provider serves many organizations. 異なる組織のユーザーを分けるために、Azure AD はテナントに分割され、組織ごとに 1 つのテナントがあります。To keep users from different organizations separate, Azure AD is partitioned into tenants, with one tenant per organization.

テナントでは、ユーザーとその関連アプリが追跡されます。Tenants keep track of users and their associated apps. Microsoft ID プラットフォームでは、個人の Microsoft アカウントでサインインするユーザーもサポートしています。The Microsoft identity platform also supports users that sign in with personal Microsoft accounts.

また、Azure AD では、組織がユーザー (通常は、Google アカウントなどのソーシャル ID を使用) をサインインさせることができるように Azure Active Directory B2C を提供しています。Azure AD also provides Azure Active Directory B2C so that organizations can sign in users, typically customers, using social identities like a Google account. 詳細については、Azure Active Directory B2C のドキュメントに関するページを参照してください。For more information, see Azure Active Directory B2C documentation .

セキュリティ トークンSecurity tokens

セキュリティ トークンには、ユーザーとアプリに関する情報が含まれます。Security tokens contain information about users and apps. Azure AD で使用される JSON ベースのトークン (JWT) に要求が含まれます。Azure AD uses JSON based tokens (JWTs) that contain claims. 要求により、あるエンティティに関するアサーションが別のエンティティに提供されます。A claim provides assertions about one entity to another. アプリケーションでは、次のようなさまざまなタスクの要求を使用できます。Applications can use claims for various tasks such as:

  • トークンを検証するValidating the token
  • サブジェクトのディレクトリ テナントを識別するIdentifying the subject's directory tenant
  • ユーザー情報を表示するDisplaying user information
  • サブジェクトの承認を判断するDetermining the subject's authorization

要求は、次のような情報を提供するキー/値ペアで構成されます。A claim consists of key-value pairs that provide information such as:

  • トークンを生成したセキュリティ トークン サーバー。the Security Token Server that generated the token.
  • トークンが生成された日付。the date when the token was generated.
  • ユーザーなどのサブジェクト (デーモンを除く)。the subject, such as the user (except for daemons).
  • 対象ユーザー。トークンが生成されたアプリです。the audience, which is the app for which the token was generated.
  • トークンを要求したアプリ (クライアント)。the app (the client) that asked for the token. Web アプリの場合、これは対象ユーザーと同じである可能性があります。In the case of web apps, this may be the same as the audience.

要求の詳細については、「Microsoft ID プラットフォーム アクセス トークン」と「Microsoft ID プラットフォームの ID トークン」を参照してください。For more detailed claim information, see the access tokens and ID tokens.

トークンを検証するには、トークンが生成されたアプリ、ユーザーをサインインさせた Web アプリ、または呼び出される Web API が必要です。It's up to the app for which the token was generated, the web app that signed-in the user, or the Web API being called, to validate the token. トークンは、秘密キーを使用してセキュリティ トークン サーバー (STS) によって署名されます。The token is signed by the Security Token Server (STS) with a private key. STS により、対応する公開キーが発行されます。The STS publishes the corresponding public key. トークンを検証するには、アプリでは、秘密キーを使用して署名が作成されたことを検証するために、STS 公開キーを使用して署名が検証されます。To validate a token, the app verifies the signature by using the STS public key to validate that the signature was created using the private key.

トークンが有効な時間は限られています。Tokens are only valid for a limited amount of time. 通常、STS では、アプリケーションまたは保護されたリソースにアクセスするためのアクセス トークンと、アクセス トークンの有効期限が近づいたときにアクセス トークンを更新するために使用する更新トークンの 2 つのトークンが提供されます。Usually the STS provides a pair of tokens: an access token to access the application or protected resource, and a refresh token used to refresh the access token when the access token is close to expiring.

アクセス トークンは、Authorization ヘッダーのベアラー トークンとして Web API に渡されます。Access tokens are passed to a Web API as the bearer token in the Authorization header. アプリでは、STS に更新トークンを提供できます。アプリへのユーザー アクセスが取り消されていない場合、新しいアクセス トークンと新しい更新トークンが返されます。An app can provide a refresh token to the STS, and if the user access to the app wasn't revoked, it will get back a new access token and a new refresh token. ユーザーが退職する場合、この方法を使用して対処します。This is how the scenario of someone leaving the enterprise is handled. ユーザーが承認されなくなると、STS で更新トークンを受け取っても、有効なアクセス トークンは新たに発行されません。When the STS receives the refresh token, it won't issue another valid access token if the user is no longer authorized.

アプリケーション モデルApplication model

アプリケーションでは、ユーザー自身をサインインさせることも、ID プロバイダーにサインインを委任することもできます。Applications can sign in users themselves or delegate sign-in to an identity provider. Azure AD でサポートされるサインイン シナリオの詳細については、「認証フローとアプリケーションのシナリオ」を参照してください。See Authentication flows and app scenarios to learn about sign-in scenarios supported by Azure AD.

ID プロバイダーで、ユーザーが特定のアプリにアクセスできることを認識するためには、ユーザーとアプリケーションの両方を ID プロバイダーに登録する必要があります。For an identity provider to know that a user has access to a particular app, both the user and the application must be registered with the identity provider. アプリケーションを Azure AD に登録するとき、アプリケーションの ID 構成を提供します。これによって Azure AD との連携が可能となります。When you register your application with Azure AD, you are providing an identity configuration for your application that allows it to integrate with Azure AD. アプリを登録すると、次のことも可能になります。Registering the app also allows you to:

  • サインイン ダイアログで、アプリケーションのブランド化をカスタマイズします。customize the branding of your application in the sign-in dialog. これは、ユーザーがアプリを初めて使用するときに目にするため重要です。This is important because this is the first experience a user will have with your app.
  • ユーザーが組織に属している場合にのみサインインできるようにするかどうかを決定します。decide if you want to let users sign in only if they belong to your organization. これはシングル テナント アプリケーションです。This is a single tenant application. または、ユーザーが職場または学校のアカウントを使用してサインインできるようにします。Or allow users to sign in using any work or school account. これはマルチ テナント アプリケーションです。This is a multi-tenant application. また、個人の Microsoft アカウントや、LinkedIn、Google などのソーシャル アカウントを許可することもできます。You can also allow personal Microsoft accounts, or a social account from LinkedIn, Google, and so on.
  • スコープのアクセス許可を要求します。request scope permissions. たとえば、サインインしたユーザーのプロファイルを読み取るためのアクセス許可を付与する "user. read" スコープを要求できます。For example, you can request the "user.read" scope, which grants permission to read the profile of the signed-in user.
  • Web API へのアクセスを定義するスコープを定義します。define scopes that define access to your Web API. 通常、アプリで API にアクセスする場合、定義したスコープへのアクセス許可を要求する必要があります。Typically, when an app wants to access your API, it will need to request permissions to the scopes you define.
  • Azure AD にアプリの ID を証明するシークレットを Azure AD と共有します。share a secret with Azure AD that proves the app's identity to Azure AD. これは、アプリが機密クライアント アプリケーションである場合に関連します。This is relevant in the case where the app is a confidential client application. 機密クライアント アプリケーションは、資格情報を安全に保持できるアプリケーションです。A confidential client application is an application that can hold credentials securely. 資格情報を格納するには、信頼されたバックエンド サーバーが必要です。They require a trusted backend server to store the credentials.

アプリケーションが登録されると、トークンの要求時に Azure AD と共有する GUID が付与されます。Once registered, the application will be given a GUID that the app shares with Azure AD when it requests tokens. アプリが機密クライアント アプリケーションである場合は、証明書またはシークレットが使用されたかどうかに応じて、秘密キーまたは公開キーも共有されます。If the app is a confidential client application, it will also share the secret or the public key, depending on whether certificates or secrets were used.

Microsoft ID プラットフォームは、次の 2 つの主な機能を果たすモデルを使用するアプリケーションを表します。The Microsoft identity platform represents applications using a model that fulfills two main functions:

サポートされる認証プロトコルでアプリが識別され、認証に必要なすべての識別子、URL、シークレット、および関連情報が提供されます。Identify the app by the authentication protocols it supports and provide all the identifiers, URLs, secrets, and related information that are needed to authenticate. Microsoft ID プラットフォームでは、以下が行われます。The Microsoft identity platform:

  • 実行時に認証をサポートするために必要なすべてのデータを保持します。Holds all the data required to support authentication at runtime.
  • アプリでアクセスする必要のあるリソースと、特定の要求がどのような状況下で満たされる必要があるかどうかを決定するための、すべてのデータを保持します。Holds all the data for deciding what resources an app might need to access, and under what circumstances a given request should be fulfilled.
  • アプリ開発者のテナント内とその他の任意の Azure AD テナントにアプリ プロビジョニングを実装するためのインフラストラクチャを提供します。Provides infrastructure for implementing app provisioning within the app developer's tenant, and to any other Azure AD tenant.
  • トークンの要求時にユーザーの同意を処理し、テナント間でのアプリの動的プロビジョニングを容易にするHandles user consent during token request time and facilitate the dynamic provisioning of apps across tenants

同意とは、リソース所有者からクライアント アプリケーションに承認 (リソース所有者に代わって特定の権限で保護されたリソースにアクセスするための) を付与するプロセスです。Consent is the process of a resource owner granting authorization for a client application to access protected resources, under specific permissions, on behalf of the resource owner. Microsoft ID プラットフォームでは、以下が行われます。The Microsoft identity platform:

  • ユーザーと管理者が、その代理としてアプリがリソースにアクセスすることの同意を、動的に付与または拒否できるようにします。Enables users and administrators to dynamically grant or deny consent for the app to access resources on their behalf.
  • 管理者が、アプリに許可する操作と特定のアプリを使用できるユーザー、およびディレクトリのリソースにアクセスする方法を、最終的に決定できるようにします。Enables administrators to ultimately decide what apps are allowed to do and which users can use specific apps, and how the directory resources are accessed.

Microsoft ID プラットフォームでは、アプリケーション オブジェクトはアプリケーションを抽象エンティティとして記述します。In the Microsoft identity platform, an application object describes an application as an abstract entity. デプロイ時に、Microsoft ID プラットフォームではアプリケーション オブジェクトがブループリントとして使用され、ディレクトリまたはテナント内のアプリケーションの具体的なインスタンスを表すサービス プリンシパルが作成されます。At deployment time, the Microsoft identity platform uses the application object as a blueprint to create a service principal, which represents a concrete instance of an application within a directory or tenant. サービス プリンシパルは、特定のターゲット ディレクトリでアプリが実際に何ができるか、誰がそれを使用できるか、どのリソースにアクセスできるのか、などを定義します。The service principal defines what the app can actually do in a specific target directory, who can use it, what resources it has access to, and so on. Microsoft ID プラットフォームでは、同意により、アプリケーション オブジェクトからサービス プリンシパルが作成されます。The Microsoft identity platform creates a service principal from an application object through consent.

次の図は、同意に基づくシンプルな Microsoft ID プラットフォーム プロビジョニングの流れを示しています。The following diagram shows a simplified Microsoft identity platform provisioning flow driven by consent. 2 つのテナント (A と B) があります。It shows two tenants (A and B). テナント A はアプリケーションを所有しています。Tenant A owns the application. テナント B は、サービス プリンシパルを使用して、アプリケーションをインスタンス化します。Tenant B is instantiating the application via a service principal.

同意に基づくシンプルなプロビジョニングの流れ

このプロビジョニングの流れは次のとおりです。In this provisioning flow:

  1. テナント B のユーザーがアプリでサインインしようとすると、承認エンドポイントがアプリケーションのトークンを要求します。A user from tenant B attempts to sign in with the app, the authorization endpoint requests a token for the application.
  2. 認証のためにユーザーの資格情報が取得および検証されます。The user credentials are acquired and verified for authentication.
  3. ユーザーは、アプリからテナント B にアクセスすることに同意するように求められます。The user is prompted to provide consent for the app to gain access to tenant B.
  4. Microsoft ID プラットフォームでは、テナント B にサービス プリンシパルを作成するためのブループリントとして、テナント A のアプリケーション オブジェクトが使用されます。The Microsoft identity platform uses the application object in tenant A as a blueprint for creating a service principal in tenant B.
  5. ユーザーは、要求されたトークンを受け取ります。The user receives the requested token.

追加のテナントに対してこのプロセスを繰り返すことができます。You can repeat this process for additional tenants. テナント A は、アプリ (アプリケーション オブジェクト) のブループリントを保持します。Tenant A retains the blueprint for the app (application object). アプリに同意が与えられている他のすべてのテナントのユーザーと管理者は、各テナントの対応するサービス プリンシパル オブジェクトから、アプリケーションに許可されている操作を引き続き制御します。Users and admins of all the other tenants where the app is given consent keep control over what the application is allowed to do via the corresponding service principal object in each tenant. 詳細については、Microsoft ID プラットフォームのアプリケーション オブジェクトとサービス プリンシパル オブジェクトに関するページを参照してください。For more information, see Application and service principal objects in Microsoft identity platform.

Azure AD を使用した Web アプリのサインイン フローWeb app sign-in flow with Azure AD

ユーザーがブラウザーで Web アプリに移動すると、次のことが起こります。When a user navigates in the browser to a web app, the following happens:

  • Web アプリで、ユーザーが認証されているかどうかが判断されます。The web app determines whether the user is authenticated.
  • ユーザーが認証されていない場合は、ユーザーをサインインさせるように Web アプリから Azure AD に委任されます。If the user isn't authenticated, the web app delegates to Azure AD to sign in the user. そのサインインは、ユーザーに資格情報を入力する、多要素認証を使用する、パスワードをまったく使用しない (Windows Hello を使用するなど) ように求めることを意味する可能性のある組織のポリシーに準拠します。That sign in will be compliant with the policy of the organization, which may mean asking the user to enter their credentials, using multi-factor-authentication, or not using a password at all (for example using Windows Hello).
  • ユーザーは、クライアント アプリが必要とするアクセスに同意するように求められます。The user is asked to consent to the access that the client app needs. これは、ユーザーが同意したアクセスを表すトークンを Azure AD で配信できるように、クライアント アプリを Azure AD に登録する必要があるためです。This is why client apps need to be registered with Azure AD, so that Azure AD can deliver tokens representing the access that the user has consented to.

ユーザーが正常に認証されると、次のことが起こります。When the user has successfully authenticated:

  • Azure AD で、Web アプリにトークンが送信されます。Azure AD sends a token to the web app.
  • Cookie が保存され、Azure AD のドメインに関連付けられ、ブラウザーの cookie jar にユーザーの ID が含まれます。A cookie is saved, associated with Azure AD's domain, that contains the identity of the user in the browser's cookie jar. 次回、アプリがブラウザーを使用して Azure AD 認証エンドポイントに移動するときに、ユーザーがもう一度サインインする必要がないように、ブラウザーから Cookie が提示されます。The next time an app uses the browser to navigate to the Azure AD authorization end point, the browser presents the cookie so that the user doesn't have to sign in again. これも SSO の実現方法です。This is also the way that SSO is achieved. Cookie は Azure AD によって生成され、内容は Azure AD によってのみ理解されます。The cookie is produced by Azure AD and can only be understood by Azure AD.
  • その後、Web アプリにより、トークンが検証されます。The web app then validates the token. 検証が成功した場合、Web アプリで、保護されたページが表示され、セッション Cookie がブラウザーの cookie jar に保存されます。If the validation succeeds, the web app displays the protected page and saves a session cookie in the browser's cookie jar. ユーザーが別のページに移動すると、Web アプリでは、そのユーザーがセッション Cookie に基づいて認証されていることを認識します。When the user navigates to another page, the web app knows that the user is authenticated based on the session cookie.

次のシーケンス図は、この相互作用をまとめたものです。The following sequence diagram summarizes this interaction:

Web アプリの認証プロセス

Web アプリで、ユーザーが認証されているかどうかが判断されるしくみHow a web app determines if the user is authenticated

Web アプリの開発者は、すべてのページまたは特定のページのみで認証を必要とするかどうかを指定できます。Web app developers can indicate whether all or only certain pages require authentication. たとえば、ASP.NET/ASP.NET Core では、[Authorize] 属性をコントローラー アクションに追加してこれを行います。For example, in ASP.NET/ASP.NET Core, this is done by adding the [Authorize] attribute to the controller actions.

この属性により、ASP.NET で、ユーザーの ID が含まれるセッション Cookie の存在が確認されます。This attribute causes ASP.NET to check for the presence of a session cookie containing the identity of the user. Cookie が存在しない場合、ASP.NET により、指定された ID プロバイダーに認証がリダイレクトされます。If a cookie isn't present, ASP.NET redirects authentication to the specified identity provider. ID プロバイダーが Azure AD 場合、Web アプリにより、 https://login.microsoftonline.com に認証がリダイレクトされ、サインイン ダイアログが表示されます。If the identity provider is Azure AD, the web app redirects authentication to https://login.microsoftonline.com, which displays a sign-in dialog.

Web アプリでサインインが Azure AD に委任され、トークンが取得されるしくみHow a web app delegates sign-in to Azure AD and obtains a token

ユーザー認証は、ブラウザーを介して行われます。User authentication happens via the browser. OpenID プロトコルで、標準の HTTP プロトコル メッセージが使用されます。The OpenID protocol uses standard HTTP protocol messages.

  • Web アプリでは、HTTP 202 (リダイレクト) がブラウザーに送信され、Azure AD が使用されます。The web app sends an HTTP 202 (redirect) to the browser to use Azure AD.
  • ユーザーが認証されると、Azure AD では、ブラウザーからリダイレクトを使用して Web アプリにトークンが送信されます。When the user is authenticated, Azure AD sends the token to the web app by using a redirect through the browser.
  • リダイレクトは、リダイレクト URI の形式で Web アプリから提供されます。The redirect is provided by the web app in the form of a redirect URI. このリダイレクト URI は、Azure AD アプリケーション オブジェクトに登録されます。This redirect URI is registered with the Azure AD application object. アプリケーションは複数の URL でデプロイされる可能性があるため、リダイレクト URI は複数存在する場合があります。There can be several redirect URIs because the application may be deployed at several URLs. そのため、Web アプリで、使用するリダイレクト URI も指定する必要があります。So the web app will also need to specify the redirect URi to use.
  • Azure AD では、Web アプリから送信されるリダイレクト URI が、アプリの登録されたリダイレクト URI のいずれかであることを確認します。Azure AD verifies that the redirect URI sent by the web app is one of the registered redirect URIs for the app.

Azure AD を使用したデスクトップおよびモバイル アプリのサインイン フローDesktop and mobile app sign-in flow with Azure AD

上述したフローは、デスクトップ アプリケーションとモバイル アプリケーションに適用されますが、若干の違いがあります。The flow described above applies, with slight differences, to desktop and mobile applications.

デスクトップ アプリケーションとモバイル アプリケーションでは、認証のために、埋め込み Web コントロールまたはシステム ブラウザーを使用できます。Desktop and mobile applications can use an embedded Web control, or a system browser, for authentication. 次の図は、デスクトップ アプリまたはモバイル アプリで Microsoft 認証ライブラリ (MSAL) を使用してアクセス トークンを取得し、Web API を呼び出す方法を示しています。The following diagram shows how a Desktop or mobile app uses the Microsoft authentication library (MSAL) to acquire access tokens and call web APIs.

デスクトップ アプリのしくみ

MSAL では、ブラウザーを使用してトークンを取得し、Web アプリと同様、認証を Azure AD に委任します。MSAL uses a browser to get tokens, and as with web apps, delegates authentication to Azure AD.

Azure AD は Web アプリの場合と同じ ID Cookie をブラウザーに保存するため、ネイティブ アプリまたはモバイル アプリでシステム ブラウザーを使用する場合は、対応する Web アプリを使用してすぐに SSO を取得します。Because Azure AD saves the same identity cookie in the browser as it does for web apps, if the native or mobile app uses the system browser it will immediately get SSO with the corresponding web app.

既定では、MSAL でシステム ブラウザーが使用されます。ただし、埋め込みコントロールを使用して、より統合されたユーザー エクスペリエンスを提供する .NET Framework デスクトップ アプリケーションは除きます。By default, MSAL uses the system browser except for .NET Framework desktop applications where an embedded control is used to provide a more integrated user experience.

次の手順Next steps

一般的な用語について理解を深めるには、「Microsoft ID プラットフォーム開発者向け用語集」を参照してください。See the Microsoft identity platform developer glossary to get familiar with common terms. Microsoft ID プラットフォームでサポートされているユーザーを認証するためのその他のシナリオの詳細については、「認証フローとアプリケーションのシナリオ」を参照してください。See Authentication flows and app scenarios to learn more about other scenarios for authenticating users supported by the Microsoft identity platform. Microsoft アカウント、Azure AD アカウント、および Azure AD B2C ユーザーを 1 つの合理化されたプログラミング モデルで使用するアプリケーションの開発に役立つ Microsoft ライブラリの詳細については、「Microsoft Authentication Library (MSAL) の概要」を参照してください。See MSAL libraries to learn about the Microsoft libraries that help you develop applications that work with Microsoft Accounts, Azure AD accounts, and Azure AD B2C users all in a single, streamlined programming model.