Bu dokümanda OAuth 2.0, ne zaman kullanılacağı, istemci kimlikleri nasıl alınacağı ve .NET için Google API İstemci Kitaplığı ile nasıl kullanılacağı açıklanmaktadır.
OAuth 2.0 Protokolü
OAuth 2.0, Google API'leri tarafından kullanılan yetkilendirme protokolüdür. Aşağıdaki bağlantıları okuyarak protokol hakkında bilgi edinebilirsiniz:
İstemci kimliklerini ve sırlarını edinme
İstemci kimliklerini ve gizli anahtarları Google API Konsolu'nda bulabilirsiniz. Farklı istemci kimliği türleri vardır. Bu nedenle, uygulamanız için doğru türü aldığınızdan emin olun:
- Web uygulaması istemci kimlikleri
- Yüklü uygulama istemci kimlikleri
- Hizmet hesabı istemci kimlikleri
Aşağıdaki kod snippet'lerinin her birinde (birinci hizmet hesabı hariç) istemci gizli anahtarını indirmeniz ve projenizde client_secrets.json
olarak depolamanız gerekir.
Kimlik bilgileri
Kullanıcı kimlik bilgileri
UserCredential
, korunan kaynaklara erişmek için erişim jetonu kullanan mesaj dizisi güvenli bir yardımcı sınıftır.
Erişim jetonunun süresi genellikle 1 saat sonra dolar. Bu durumda, kullanmaya çalışırsanız hata mesajı alırsınız.
UserCredential
ve AuthorizationCodeFlow
jetonda otomatik olarak "yenileme"
işlemi gerçekleştirir. Bu da yeni bir erişim jetonu almak anlamına gelir.
Bu işlem, yetkilendirme kodu akışı sırasında access_type=offline
parametresini kullanırsanız erişim jetonuyla birlikte aldığınız uzun ömürlü yenileme jetonu kullanılarak yapılır.
Çoğu uygulamada, kimlik bilgisinin erişim jetonunun ve yenileme jetonunu kalıcı depolamada saklamanız önerilir. Aksi takdirde, erişim jetonunun süresi, elimize ulaştıktan bir saat sonra sona ereceği için son kullanıcıya saatte bir yetkilendirme sayfası sunmanız gerekir.
Erişim ve yenileme jetonlarının kalıcı olmasını sağlamak için IDataStore
için kendi uygulamanızı sağlayabilir veya kitaplık tarafından sağlanan aşağıdaki uygulamalardan birini kullanabilirsiniz:
-
.NET için
FileDataStore
, kimlik bilgilerinin bir dosyada kalıcı olmasını sağlar.
Hizmet Hesabı Kimlik Bilgisi
ServiceAccountCredential
, UserCredential
ile benzerdir ancak farklı bir amaca hizmet eder.
Google OAuth 2.0, web uygulaması ve Google Cloud Storage arasındaki etkileşim gibi sunucudan sunucuya etkileşimleri destekler.
İstekte bulunan uygulamanın bir API'ye erişmek için kendi kimliğini doğrulaması gerekir ve son kullanıcının bu sürece dahil olması gerekmez.
ServiceAccountCredential
, yeni bir erişim jetonu almak üzere isteği imzalamak için kullanılan özel bir anahtar depolar.
Hem UserCredential
hem de ServiceAccountCredential
, IConfigurableHttpClientInitializer
'yi uygular. Böylece, bunların her birini şu şekilde kaydedebilirsiniz:
- Başarısız bir yanıt işleyici. Bu nedenle, HTTP
401
durum kodu alırsa jetonu yeniler. - Her istekte
Authorization
üstbilgisine müdahale eden bir müdahale eden.
Yüklü uygulamalar
Books API'yi kullanan örnek kod:
using System; using System.IO; using System.Threading; using System.Threading.Tasks; using Google.Apis.Auth.OAuth2; using Google.Apis.Books.v1; using Google.Apis.Books.v1.Data; using Google.Apis.Services; using Google.Apis.Util.Store; namespace Books.ListMyLibrary { /// <summary> /// Sample which demonstrates how to use the Books API. /// https://developers.google.com/books/docs/v1/getting_started /// <summary> internal class Program { [STAThread] static void Main(string[] args) { Console.WriteLine("Books API Sample: List MyLibrary"); Console.WriteLine("================================"); try { new Program().Run().Wait(); } catch (AggregateException ex) { foreach (var e in ex.InnerExceptions) { Console.WriteLine("ERROR: " + e.Message); } } Console.WriteLine("Press any key to continue..."); Console.ReadKey(); } private async Task Run() { UserCredential credential; using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read)) { credential = await GoogleWebAuthorizationBroker.AuthorizeAsync( GoogleClientSecrets.Load(stream).Secrets, new[] { BooksService.Scope.Books }, "user", CancellationToken.None, new FileDataStore("Books.ListMyLibrary")); } // Create the service. var service = new BooksService(new BaseClientService.Initializer() { HttpClientInitializer = credential, ApplicationName = "Books API Sample", }); var bookshelves = await service.Mylibrary.Bookshelves.List().ExecuteAsync(); ... } } }
-
Bu örnek kodda
GoogleWebAuthorizationBroker.AuthorizeAsync
yöntemi çağrılarak yeni birUserCredential
örneği oluşturulur. Bu statik yöntem aşağıdaki gibi olur:- İstemci gizli anahtarı (veya istemci gizli anahtarı akışı).
- Gerekli kapsamlar.
- Kullanıcı tanımlayıcısı.
- Bir işlemi iptal etmek için kullanılan iptal jetonu.
- İsteğe bağlı bir veri deposu. Veri deposu belirtilmezse varsayılan olarak
Google.Apis.Auth
klasörüne sahip birFileDataStore
kullanılır. Klasör,Environment.SpecialFolder.ApplicationData
içinde oluşturuldu.
-
Bu yöntemin döndürdüğü
UserCredential
,BooksService
üzerinde birHttpClientInitializer
olarak ayarlanır (başlatıcı kullanılarak). Yukarıda açıklandığı gibiUserCredential
, bir HTTP istemci başlatıcı uygular. -
Yukarıdaki örnek kodda, istemci gizli bilgilerinin bir dosyadan yüklendiğini unutmayın ancak aşağıdakileri de yapabilirsiniz:
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync( new ClientSecrets { ClientId = "PUT_CLIENT_ID_HERE", ClientSecret = "PUT_CLIENT_SECRETS_HERE" }, new[] { BooksService.Scope.Books }, "user", CancellationToken.None, new FileDataStore("Books.ListMyLibrary"));
Kitaplar örneğimize göz atın.
Web uygulamaları (ASP.NET Core 3)
Google API'leri, Web Sunucusu Uygulamaları için OAuth 2.0'ı destekler.
Google.Apis.Auth.AspNetCore3, ASP.NET Core 3 uygulamalarındaki çoğu Google tabanlı OAuth 2.0 senaryosu için
kullanılması önerilen kitaplıktır. Google'a özel bir OpenIdConnect
kimlik doğrulama işleyicisi uygular. Artımlı kimlik doğrulamayı destekler ve Google API'leri ile kullanılabilecek Google kimlik bilgilerini sağlamak için enjekte edilebilir IGoogleAuthProvider
özelliğini tanımlar.
Bu bölümde, Google.Apis.Auth.AspNetCore3 yapılandırması ve kullanımı açıklanmaktadır. Burada gösterilen kod, tamamen çalışan, standart bir ASP.NET Core 3 uygulaması olan Google.Apis.Auth.AspNetCore3.IntegrationTests tabanlıdır.
Bu dokümanı eğitim olarak kullanmak istiyorsanız kendi ASP.NET Core 3 uygulamanıza ve bu adımları bir ön koşul olarak tamamlamanıza yardımcı olacaktır.
Ön koşullar
- Google.Apis.Auth.AspNetCore3 paketini yükleyin.
- Google Drive API'yi kullandığımız için Google.Apis.Drive.v3 paketini de yüklemeniz gerekiyor.
- Henüz oluşturmadıysanız bir Google Cloud projesi oluşturun. Bunu yapmak için bu talimatları uygulayın. Bu, uygulamanızın tanımlandığı proje olacaktır.
- Google Drive API'yi etkinleştirdiğinizden emin olun. API'leri etkinleştirmek için şu talimatları uygulayın.
-
Uygulamanızı Google'a tanıtacak yetkilendirme kimlik bilgileri oluşturun. Yetkilendirme kimlik bilgileri oluşturmak ve
client_secrets.json
dosyasını indirmek için bu talimatları uygulayın. İki öne çıkan özellik:- Kimlik bilgileri' türünün Web uygulaması olması gerektiğine dikkat edin.
- Bu uygulamayı çalıştırmak için eklemeniz gereken tek yönlendirme URI'si
https://localhost:5001/signin-oidc
'dir.
Uygulamanızı Google.Apis.Auth.AspNetCore3 kullanacak şekilde yapılandırın
Google.Apis.Auth.AspNetCore3, Startup
sınıfında veya kullanıyor olabileceğiniz benzer bir alternatifte yapılandırılır. Aşağıdaki snippet'ler, Google.Apis.Auth.AspNetCore3.IntegrationTests projesindeki Startup.cs
dosyasından çıkarılır.
-
Startup.cs
dosyanıza aşağıdakileri kullanarak yönerge ekleyin.using Google.Apis.Auth.AspNetCore3;
-
Startup.ConfigureServices
yönteminde aşağıdaki kodu ekleyerek istemci kimliği ve istemci gizli anahtarı yer tutucularınıclient_secrets.json
dosyasında bulunan değerlerle değiştirin. Bu değerleri doğrudan JSON dosyasından yükleyebilir veya güvenli bir şekilde saklayabilirsiniz. Bu değerlerin doğrudan JSON dosyasından nasıl yükleneceği hakkında örnek için Google.Apis.Auth.AspNetCore3.IntegrationTests projesindekiClientInfo.Load
yöntemine göz atın.public void ConfigureServices(IServiceCollection services) { ... // This configures Google.Apis.Auth.AspNetCore3 for use in this app. services .AddAuthentication(o => { // This forces challenge results to be handled by Google OpenID Handler, so there's no // need to add an AccountController that emits challenges for Login. o.DefaultChallengeScheme = GoogleOpenIdConnectDefaults.AuthenticationScheme; // This forces forbid results to be handled by Google OpenID Handler, which checks if // extra scopes are required and does automatic incremental auth. o.DefaultForbidScheme = GoogleOpenIdConnectDefaults.AuthenticationScheme; // Default scheme that will handle everything else. // Once a user is authenticated, the OAuth2 token info is stored in cookies. o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; }) .AddCookie() .AddGoogleOpenIdConnect(options => { options.ClientId = {YOUR_CLIENT_ID}; options.ClientSecret = {YOUR_CLIENT_SECRET}; }); }
-
Startup.Configure
yönteminde, kanala ASP.NET Core 3 kimlik doğrulama ve yetkilendirme ara katman yazılımı bileşenlerinin yanı sıra HTTPS yönlendirmeleri eklediğinizden emin olun:public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { ... app.UseHttpsRedirection(); ... app.UseAuthentication(); app.UseAuthorization(); ... }
Google API'lerine kendi adlarına erişmek için kullanıcı kimlik bilgisini kullanın
Kumandalarınıza Google API'lerine erişim için kullanıcı kimlik bilgisi gerektiren işlem yöntemleri eklemeye hazırsınız. Aşağıdaki snippet'te, kimliği doğrulanmış kullanıcının Google Drive hesabındaki dosyaların nasıl listeleneceği gösterilmektedir. Çoğunlukla iki şeye dikkat edin:
-
Kullanıcının kimliğinin doğrulanmasının yanı sıra, uygulamanıza
GoogleScopedAuthorize
özelliğini kullanarak belirttiğinizhttps://www.googleapis.com/auth/drive.readonly
kapsamının da verilmiş olması gerekir. -
Kullanıcının kimlik bilgilerini almak amacıyla kullandığımız bir
IGoogleAuthProvider
öğesini almak için ASP.NET Core 3'ün standart bağımlılık ekleme mekanizmasını kullanıyoruz.
Kod:
-
İlk olarak, aşağıdaki yönergeleri kullanarak kumandanıza ekleyin.
using Google.Apis.Auth.AspNetCore3; using Google.Apis.Auth.OAuth2; using Google.Apis.Drive.v3; using Google.Apis.Services;
-
Kumanda işlemini aşağıdaki gibi ekleyin (ve
IList<string>
modeli alan basit bir görünümle birlikte):/// <summary> /// Lists the authenticated user's Google Drive files. /// Specifying the <see cref="GoogleScopedAuthorizeAttribute"> will guarantee that the code /// executes only if the user is authenticated and has granted the scope specified in the attribute /// to this application. /// </summary> /// <param name="auth">The Google authorization provider. /// This can also be injected on the controller constructor.</param> [GoogleScopedAuthorize(DriveService.ScopeConstants.DriveReadonly)] public async Task<IActionResult> DriveFileList([FromServices] IGoogleAuthProvider auth) { GoogleCredential cred = await auth.GetCredentialAsync(); var service = new DriveService(new BaseClientService.Initializer { HttpClientInitializer = cred }); var files = await service.Files.List().ExecuteAsync(); var fileNames = files.Files.Select(x => x.Name).ToList(); return View(fileNames); }
Temel bilgileri burada bulabilirsiniz. Nasıl başarılı olabileceğinizi öğrenmek için Google.Apis.Auth.AspNetCore3.IntegrationTests projesinden HomeController.cs
kanalına göz atabilirsiniz:
- Belirli bir kapsam olmadan yalnızca kullanıcı kimlik doğrulaması
- Çıkış yapma işlevi
- Kod aracılığıyla ek yetkilendirme. Yukarıdaki snippet'in özellikler aracılığıyla artımlı yetkilendirme gösterdiğini unutmayın.
- Şu anda izin verilen kapsamları inceleyin
- Erişimi inceleyin ve jetonları yenileyin
- Erişim jetonunu zorla yenile. Google.Apis.Auth.AspNetCore3, erişim jetonunun süresinin dolmadığını veya süresi dolmak üzere olduğunu algılayıp otomatik olarak yenileneceği için bunu sizin yapmanız gerekmez.
Web uygulamaları (ASP.NET MVC)
Google API'leri, Web Sunucusu Uygulamaları için OAuth 2.0'ı destekler.
Aşağıdaki kodu başarıyla çalıştırmak için önce Google API Konsolu'nda projenize bir yönlendirme URI'si eklemeniz gerekir.
FlowMetadata
ve varsayılan ayarlarını kullanacağınız için yönlendirme URI'sini your_site/AuthCallback/IndexAsync
olarak ayarlayın.
OAuth 2.0 kimlik bilgileriniz için yönlendirme URI'lerini bulmak için aşağıdakileri yapın:
- API Konsolu'nda Kimlik bilgileri sayfası'nı açın.
- Henüz yapmadıysanız Kimlik bilgisi oluştur ve OAuth istemci kimliği'ni tıklayarak OAuth 2.0 kimlik bilgilerinizi oluşturun.
- Kimlik bilgilerinizi oluşturduktan sonra OAuth 2.0 istemci kimlikleri bölümündeki istemci kimliğini (web uygulaması için) tıklayarak yönlendirme URL'lerini görüntüleyin veya düzenleyin.
IDE'nizde yeni bir web uygulaması projesi oluşturduktan sonra Drive, YouTube veya kullanmak istediğiniz diğer hizmetler için doğru Google.Apis
NuGet paketini ekleyin. Ardından Google.Apis.Auth.MVC paketini ekleyin.
Aşağıdaki kod, bir Google API hizmetini sorgulayan ASP.NET MVC uygulamasını göstermektedir.
-
Kendi
FlowMetadata
uygulamanızı ekleyin.using System; using System.Web.Mvc; using Google.Apis.Auth.OAuth2; using Google.Apis.Auth.OAuth2.Flows; using Google.Apis.Auth.OAuth2.Mvc; using Google.Apis.Drive.v2; using Google.Apis.Util.Store; namespace Google.Apis.Sample.MVC4 { public class AppFlowMetadata : FlowMetadata { private static readonly IAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer { ClientSecrets = new ClientSecrets { ClientId = "PUT_CLIENT_ID_HERE", ClientSecret = "PUT_CLIENT_SECRET_HERE" }, Scopes = new[] { DriveService.Scope.Drive }, DataStore = new FileDataStore("Drive.Api.Auth.Store") }); public override string GetUserId(Controller controller) { // In this sample we use the session to store the user identifiers. // That's not the best practice, because you should have a logic to identify // a user. You might want to use "OpenID Connect". // You can read more about the protocol in the following link: // https://developers.google.com/accounts/docs/OAuth2Login. var user = controller.Session["user"]; if (user == null) { user = Guid.NewGuid(); controller.Session["user"] = user; } return user.ToString(); } public override IAuthorizationCodeFlow Flow { get { return flow; } } } }
FlowMetadata
, kullanıcı tanımlayıcısını ve kullandığınızIAuthorizationCodeFlow
öğesini alma ile ilgili kendi mantığınızı içeren soyut bir sınıftır.Yukarıdaki örnek kodda doğru kapsamlar, istemci gizli anahtarları ve veri deposuyla yeni bir
GoogleAuthorizationCodeFlow
oluşturulur. KendiIDataStore
uygulamanızı ekleyebilirsiniz. Örneğin,EntityFramework
kullanan bir uygulama yazabilirsiniz. -
Google API hizmetini kullanan kendi denetleyicinizi uygulayın.
Aşağıdaki örnekte bir
DriveService
kullanılmaktadır:using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Web.Mvc; using Google.Apis.Auth.OAuth2.Mvc; using Google.Apis.Drive.v2; using Google.Apis.Services; using Google.Apis.Sample.MVC4; namespace Google.Apis.Sample.MVC4.Controllers { public class HomeController : Controller { public async Task<ActionResult> IndexAsync(CancellationToken cancellationToken) { var result = await new AuthorizationCodeMvcApp(this, new AppFlowMetadata()). AuthorizeAsync(cancellationToken); if (result.Credential != null) { var service = new DriveService(new BaseClientService.Initializer { HttpClientInitializer = result.Credential, ApplicationName = "ASP.NET MVC Sample" }); // YOUR CODE SHOULD BE HERE.. // SAMPLE CODE: var list = await service.Files.List().ExecuteAsync(); ViewBag.Message = "FILE COUNT IS: " + list.Items.Count(); return View(); } else { return new RedirectResult(result.RedirectUri); } } } }
-
Kendi geri çağırma denetleyicinizi uygulayın. Uygulama aşağıdaki gibi olmalıdır:
using Google.Apis.Sample.MVC4; namespace Google.Apis.Sample.MVC4.Controllers { public class AuthCallbackController : Google.Apis.Auth.OAuth2.Mvc.Controllers.AuthCallbackController { protected override Google.Apis.Auth.OAuth2.Mvc.FlowMetadata FlowData { get { return new AppFlowMetadata(); } } } }
Hizmet hesabı
Google API'leri, hizmet hesaplarını da destekler. İstemci uygulamaları, son kullanıcının verilerine erişim istediğinden farklı olarak, hizmet hesapları istemci uygulamasının kendi verilerine erişim sağlar.
İstemci uygulamanız erişim jetonu isteğini Google API Konsolu'ndan indirilmiş bir özel anahtarı kullanarak imzalar. Yeni bir istemci kimliği oluşturduktan sonra "Hizmet Hesabı" uygulama türünü seçmeniz gerekir. Ardından özel anahtarı indirebilirsiniz. Google Plus API'yi kullanan hizmet hesabı örneğimize göz atın.
using System; using System.Security.Cryptography.X509Certificates; using Google.Apis.Auth.OAuth2; using Google.Apis.Plus.v1; using Google.Apis.Plus.v1.Data; using Google.Apis.Services; namespace Google.Apis.Samples.PlusServiceAccount { /// <summary> /// This sample demonstrates the simplest use case for a Service Account service. /// The certificate needs to be downloaded from the Google API Console /// <see cref="https://console.cloud.google.com/"> /// "Create another client ID..." -> "Service Account" -> Download the certificate, /// rename it as "key.p12" and add it to the project. Don't forget to change the Build action /// to "Content" and the Copy to Output Directory to "Copy if newer". /// </summary> public class Program { // A known public activity. private static String ACTIVITY_ID = "z12gtjhq3qn2xxl2o224exwiqruvtda0i"; public static void Main(string[] args) { Console.WriteLine("Plus API - Service Account"); Console.WriteLine("=========================="); String serviceAccountEmail = "SERVICE_ACCOUNT_EMAIL_HERE"; var certificate = new X509Certificate2(@"key.p12", "notasecret", X509KeyStorageFlags.Exportable); ServiceAccountCredential credential = new ServiceAccountCredential( new ServiceAccountCredential.Initializer(serviceAccountEmail) { Scopes = new[] { PlusService.Scope.PlusMe } }.FromCertificate(certificate)); // Create the service. var service = new PlusService(new BaseClientService.Initializer() { HttpClientInitializer = credential, ApplicationName = "Plus API Sample", }); Activity activity = service.Activities.Get(ACTIVITY_ID).Execute(); Console.WriteLine(" Activity: " + activity.Object.Content); Console.WriteLine(" Video: " + activity.Object.Attachments[0].Url); Console.WriteLine("Press any key to continue..."); Console.ReadKey(); } } }
Yukarıdaki örnek kod bir ServiceAccountCredential
oluşturur.
Gerekli kapsamlar ayarlandı ve belirtilen X509Certificate2
üzerinden özel anahtarı yükleyen FromCertificate
çağrısı var.
Diğer tüm örneklerde olduğu gibi kimlik bilgisi HttpClientInitializer
olarak ayarlanır.