Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
.NET Framework 4.7.2+ üzerinde ASP.NET MVC ve Web API uygulamalarınıza Microsoft.Identity.Web.OWIN paketini kullanarak modern kimlik doğrulaması ekleyin.
OWIN tümleştirmesini anlama
Microsoft.Identity.Web.OWIN paketi, Microsoft.Identity.Web gücünü Microsoft Entra ID ile OWIN ara yazılımını kullanan ASP.NET MVC ve Web API uygulamalarına getirir.
Önemli avantajları gözden geçirme
Aşağıdaki tabloda paketin temel özellikleri ve avantajları özetlenmiştir.
| Özellik | Fayda |
|---|---|
| TokenAcquirerFactory | Önbelleğe alma ile otomatik jeton edinme |
| Denetleyici Uzantıları | Kolay erişim için GraphServiceClient ve IDownstreamApi |
| Dağıtılmış Belirteç Önbelleği | SQL Server, Redis, Cosmos DB, PostgreSQL için yerleşik destek |
| Otomatik Belirteç Yenileme | Belirteç yenilemeyi saydam olarak işler |
| Artımlı Onay | Onay akışının sorunsuz entegrasyonu |
Desteklenen senaryoları gözden geçirme
Microsoft. Identity.Web.OWIN aşağıdaki uygulama türlerini ve senaryolarını destekler.
- ASP.NET MVC Web Applications (.NET Framework 4.7.2+)
- ASP.NET Web API (.NET Framework 4.7.2+)
- Karma Uygulamalar (MVC + Web API))
- Denetleyicilerden Microsoft Graph'i Çağırma
- Otomatik kimlik doğrulaması ile Aşağı Akış API'lerini çağırma
Paketi yükle
Microsoft.Identity.Web.OWIN NuGet paketini tercih ettiğiniz yöntemi kullanarak yükleyin.
Paket Yöneticisi Console içinde aşağıdaki komutu çalıştırın:
Install-Package Microsoft.Identity.Web.OWIN
Alternatif olarak, .NET CLI ile aşağıdaki komutu çalıştırın:
dotnet add package Microsoft.Identity.Web.OWIN
Bağımlılıklar otomatik olarak dahil:
- Microsoft.Identity.Web.TokenAcquisition
- Microsoft. Identity.Web.TokenCache
- Microsoft.Owin
- System.Web
Uygulamayı yapılandırma
Uygulama ayarlarınızı Microsoft Entra ve aşağı akış API'lerine bağlanacak şekilde yapılandırın.
Web.config yapılandırma
aşağıdaki Microsoft Entra ve aşağı akış API'si ayarlarını Web.config dosyanıza ekleyin.
<configuration>
<appSettings>
<!-- Microsoft Entra ID Configuration -->
<add key="AzureAd:Instance" value="https://login.microsoftonline.com/" />
<add key="AzureAd:TenantId" value="your-tenant-id" />
<add key="AzureAd:ClientId" value="your-client-id" />
<add key="AzureAd:ClientSecret" value="your-client-secret" />
<add key="AzureAd:RedirectUri" value="https://localhost:44368/" />
<add key="AzureAd:PostLogoutRedirectUri" value="https://localhost:44368/" />
<!-- Microsoft Graph Configuration -->
<add key="DownstreamApi:MicrosoftGraph:BaseUrl" value="https://graph.microsoft.com/v1.0" />
<add key="DownstreamApi:MicrosoftGraph:Scopes" value="user.read" />
<!-- Custom Downstream API Configuration -->
<add key="DownstreamApi:TodoListService:BaseUrl" value="https://localhost:44351" />
<add key="DownstreamApi:TodoListService:Scopes" value="api://todo-api-client-id/.default" />
</appSettings>
<connectionStrings>
<!-- Optional: SQL Server Token Cache -->
<add name="TokenCache"
connectionString="Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=TokenCache;Integrated Security=True;" />
</connectionStrings>
</configuration>
appsettings.json yapılandırma (alternatif)
Ayrıca, aşağıdaki örnekte gösterildiği gibi ayarları bir appsettings.json dosyada depolayabilirsiniz.
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "your-tenant-id",
"ClientId": "your-client-id",
"ClientSecret": "your-client-secret",
"RedirectUri": "https://localhost:44368/",
"PostLogoutRedirectUri": "https://localhost:44368/"
},
"DownstreamApi": {
"MicrosoftGraph": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": "user.read"
},
"TodoListService": {
"BaseUrl": "https://localhost:44351",
"Scopes": "api://todo-api-client-id/.default"
}
}
}
Başlangıç sınıfını ayarlama
Kimlik doğrulama ara yazılımı, belirteç alma ve aşağı akış API hizmetlerini başlangıç sınıfınıza kaydedin.
App_Start/Startup.Auth.cs yapılandırma
Aşağıdaki kod, Microsoft.Identity.Web.OWIN ile eksiksiz bir kurulum göstermektedir.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.OWIN;
using Microsoft.Identity.Web.TokenCacheProviders.Distributed;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;
using System;
using System.Configuration;
using System.Web;
namespace MyMvcApp
{
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
// Set default authentication type
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
// Configure cookie authentication
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
CookieName = "MyApp.Auth",
ExpireTimeSpan = TimeSpan.FromHours(1),
SlidingExpiration = true
});
// Configure OpenID Connect authentication
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = ConfigurationManager.AppSettings["AzureAd:ClientId"],
Authority = $"https://login.microsoftonline.com/{ConfigurationManager.AppSettings["AzureAd:TenantId"]}",
RedirectUri = ConfigurationManager.AppSettings["AzureAd:RedirectUri"],
PostLogoutRedirectUri = ConfigurationManager.AppSettings["AzureAd:PostLogoutRedirectUri"],
Scope = "openid profile email offline_access",
ResponseType = "code id_token",
TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
NameClaimType = "preferred_username"
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = context =>
{
context.HandleResponse();
context.Response.Redirect("/Error?message=" + context.Exception.Message);
return Task.FromResult(0);
}
}
});
// Configure Microsoft Identity Web services
var services = CreateOwinServiceCollection();
// Add token acquisition
services.AddTokenAcquisition();
// Add Microsoft Graph support
services.AddMicrosoftGraph();
// Add downstream API support
services.AddDownstreamApi("MicrosoftGraph", services.BuildServiceProvider()
.GetRequiredService<IConfiguration>().GetSection("DownstreamApi:MicrosoftGraph"));
services.AddDownstreamApi("TodoListService", services.BuildServiceProvider()
.GetRequiredService<IConfiguration>().GetSection("DownstreamApi:TodoListService"));
// Configure token cache (choose one option)
ConfigureTokenCache(services);
// Build service provider
var serviceProvider = services.BuildServiceProvider();
// Create and register token acquirer factory
var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
tokenAcquirerFactory.Build(serviceProvider);
// Add OWIN token acquisition middleware
app.Use<OwinTokenAcquisitionMiddleware>(tokenAcquirerFactory);
}
private IServiceCollection CreateOwinServiceCollection()
{
var services = new ServiceCollection();
// Add configuration from appsettings.json and/or Web.config
IConfiguration configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: true)
.AddInMemoryCollection(new Dictionary<string, string>
{
["AzureAd:Instance"] = ConfigurationManager.AppSettings["AzureAd:Instance"],
["AzureAd:TenantId"] = ConfigurationManager.AppSettings["AzureAd:TenantId"],
["AzureAd:ClientId"] = ConfigurationManager.AppSettings["AzureAd:ClientId"],
["AzureAd:ClientSecret"] = ConfigurationManager.AppSettings["AzureAd:ClientSecret"],
["DownstreamApi:MicrosoftGraph:BaseUrl"] = ConfigurationManager.AppSettings["DownstreamApi:MicrosoftGraph:BaseUrl"],
["DownstreamApi:MicrosoftGraph:Scopes"] = ConfigurationManager.AppSettings["DownstreamApi:MicrosoftGraph:Scopes"],
})
.Build();
services.AddSingleton(configuration);
return services;
}
private void ConfigureTokenCache(IServiceCollection services)
{
// Option 1: In-memory cache (development)
services.AddDistributedTokenCaches(cacheServices =>
{
cacheServices.AddDistributedMemoryCache();
});
// Option 2: SQL Server cache (production)
/*
services.AddDistributedTokenCaches(cacheServices =>
{
cacheServices.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = ConfigurationManager.ConnectionStrings["TokenCache"].ConnectionString;
options.SchemaName = "dbo";
options.TableName = "TokenCache";
options.DefaultSlidingExpiration = TimeSpan.FromMinutes(90);
});
});
*/
// Option 3: Redis cache (production, high-scale)
/*
services.AddDistributedTokenCaches(cacheServices =>
{
cacheServices.AddStackExchangeRedisCache(options =>
{
options.Configuration = ConfigurationManager.AppSettings["Redis:ConnectionString"];
options.InstanceName = "MyMvcApp_";
});
});
*/
}
}
}
Denetleyicileri tümleştirme
Paket tarafından sağlanan uzantı yöntemlerini kullanarak denetleyicilerinizden Microsoft Graph ve aşağı akış API'lerine erişin.
MVC denetleyicilerini tümleştirme
Aşağıdaki örnekte, Microsoft Graph erişmek için denetleyici uzantısı yöntemlerinin nasıl kullanılacağı gösterilmektedir:
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.OWIN;
using Microsoft.Graph;
using System.Threading.Tasks;
using System.Web.Mvc;
namespace MyMvcApp.Controllers
{
[Authorize]
public class HomeController : Controller
{
// GET: Home/Index
public async Task<ActionResult> Index()
{
try
{
// Access Microsoft Graph using extension method
var graphClient = this.GetGraphServiceClient();
var user = await graphClient.Me.GetAsync();
ViewBag.UserName = user.DisplayName;
ViewBag.Email = user.Mail ?? user.UserPrincipalName;
ViewBag.JobTitle = user.JobTitle;
return View();
}
catch (MsalUiRequiredException)
{
// Incremental consent required
return new ChallengeResult();
}
catch (Exception ex)
{
return View("Error", new ErrorViewModel { Message = ex.Message });
}
}
// GET: Home/Profile
public async Task<ActionResult> Profile()
{
var graphClient = this.GetGraphServiceClient();
// Get user profile
var user = await graphClient.Me
.GetAsync(requestConfig => requestConfig.QueryParameters.Select = new[] { "displayName", "mail", "jobTitle", "department" });
return View(user);
}
// GET: Home/Photo
public async Task<ActionResult> Photo()
{
var graphClient = this.GetGraphServiceClient();
try
{
// Get user photo
var photoStream = await graphClient.Me.Photo.Content.GetAsync();
return File(photoStream, "image/jpeg");
}
catch (ServiceException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
{
return File(Server.MapPath("~/Content/images/default-user.png"), "image/png");
}
}
}
}
Web API denetleyicilerini tümleştirme
Aşağıdaki örnekte, aşağı akış API'sini çağırmak için ApiController uzantısı yöntemlerinin nasıl kullanılacağı gösterilmektedir:
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.OWIN;
using Microsoft.Identity.Abstractions;
using System.Threading.Tasks;
using System.Web.Http;
namespace MyWebApi.Controllers
{
[Authorize]
[RoutePrefix("api/todos")]
public class TodoController : ApiController
{
// GET: api/todos
[HttpGet]
[Route("")]
public async Task<IHttpActionResult> GetTodos()
{
try
{
// Call downstream API using extension method
var downstreamApi = this.GetDownstreamApi();
var todos = await downstreamApi.GetForUserAsync<List<TodoItem>>(
"TodoListService",
options =>
{
options.RelativePath = "api/todolist";
});
return Ok(todos);
}
catch (MsalUiRequiredException)
{
return Unauthorized();
}
catch (HttpRequestException ex)
{
return InternalServerError(ex);
}
}
// POST: api/todos
[HttpPost]
[Route("")]
public async Task<IHttpActionResult> CreateTodo([FromBody] TodoItem todo)
{
var downstreamApi = this.GetDownstreamApi();
var createdTodo = await downstreamApi.PostForUserAsync<TodoItem, TodoItem>(
"TodoListService",
todo,
options =>
{
options.RelativePath = "api/todolist";
});
return Created($"api/todos/{createdTodo.Id}", createdTodo);
}
}
}
Microsoft Graph'ı Çağır
GraphServiceClient kullanarak denetleyicilerinizden Microsoft Graph verilerle etkileşime geçin.
Microsoft Graph istemcisini ayarlama
Microsoft Graph istemcisi şu çağrıyla Startup.Auth.cs'da zaten yapılandırılmıştır:
services.AddMicrosoftGraph();
Denetleyicilerde GraphServiceClient kullanma
Aşağıdaki örnek, bir MVC denetleyicisindeki yaygın Microsoft Graph işlemlerini gösterir.
[Authorize]
public class GraphController : Controller
{
public async Task<ActionResult> MyProfile()
{
var graphClient = this.GetGraphServiceClient();
var user = await graphClient.Me.GetAsync();
return View(user);
}
public async Task<ActionResult> MyManager()
{
var graphClient = this.GetGraphServiceClient();
var manager = await graphClient.Me.Manager.GetAsync();
return View(manager);
}
public async Task<ActionResult> MyDirectReports()
{
var graphClient = this.GetGraphServiceClient();
var directReports = await graphClient.Me.DirectReports.GetAsync();
return View(directReports.Value);
}
public async Task<ActionResult> SendEmail([FromBody] EmailMessage message)
{
var graphClient = this.GetGraphServiceClient();
var email = new Message
{
Subject = message.Subject,
Body = new ItemBody
{
ContentType = BodyType.Text,
Content = message.Body
},
ToRecipients = new[]
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = message.To
}
}
}
};
await graphClient.Me.SendMail.PostAsync(new SendMailPostRequestBody
{
Message = email
});
return RedirectToAction("Index");
}
}
Aşağı akış API'lerini çağırma
Denetleyicilerinizden otomatik belirteç alma ile aşağı akış API'lerini kaydedin ve çağırın.
Aşağı akış API'lerini yapılandırma
aşağı akış API'sini Startup.Auth.cs aşağıdaki kodla kaydedin:
services.AddDownstreamApi("TodoListService", configuration.GetSection("DownstreamApi:TodoListService"));
İlgili ayarları Web.config ekleyin.
<add key="DownstreamApi:TodoListService:BaseUrl" value="https://localhost:44351" />
<add key="DownstreamApi:TodoListService:Scopes" value="api://todo-api-client-id/.default" />
Denetleyicilerde IDownstreamApi kullanma
Aşağıdaki örnekte, MVC denetleyicisinden aşağı akış API'sine karşı CRUD işlemlerinin nasıl gerçekleştirıldığı gösterilmektedir.
[Authorize]
public class TodoController : Controller
{
// GET all todos
public async Task<ActionResult> Index()
{
var downstreamApi = this.GetDownstreamApi();
var todos = await downstreamApi.GetForUserAsync<List<TodoItem>>(
"TodoListService",
options =>
{
options.RelativePath = "api/todolist";
});
return View(todos);
}
// GET specific todo
public async Task<ActionResult> Details(int id)
{
var downstreamApi = this.GetDownstreamApi();
var todo = await downstreamApi.GetForUserAsync<TodoItem>(
"TodoListService",
options =>
{
options.RelativePath = $"api/todolist/{id}";
});
return View(todo);
}
// POST new todo
[HttpPost]
public async Task<ActionResult> Create(TodoItem todo)
{
var downstreamApi = this.GetDownstreamApi();
var createdTodo = await downstreamApi.PostForUserAsync<TodoItem, TodoItem>(
"TodoListService",
todo,
options =>
{
options.RelativePath = "api/todolist";
});
return RedirectToAction("Index");
}
// PUT update todo
[HttpPost]
public async Task<ActionResult> Edit(int id, TodoItem todo)
{
var downstreamApi = this.GetDownstreamApi();
await downstreamApi.CallApiForUserAsync(
"TodoListService",
options =>
{
options.HttpMethod = HttpMethod.Put;
options.RelativePath = $"api/todolist/{id}";
options.RequestBody = todo;
});
return RedirectToAction("Index");
}
// DELETE todo
[HttpPost]
public async Task<ActionResult> Delete(int id)
{
var downstreamApi = this.GetDownstreamApi();
await downstreamApi.CallApiForUserAsync(
"TodoListService",
options =>
{
options.HttpMethod = HttpMethod.Delete;
options.RelativePath = $"api/todolist/{id}";
});
return RedirectToAction("Index");
}
}
Örnek uygulamaları keşfetme
Aşağıdaki örnekleri kullanarak Microsoft.Identity.Web.OWIN'i iş başında görün.
Resmi Microsoft örneklerini gözden geçirin
Aşağıdaki tabloda, Microsoft.Identity.Web.OWIN tümleştirmesini gösteren resmi örnekler listelenmiştir.
| Örnek | Açıklama |
|---|---|
| ms-identity-aspnet-webapp-openidconnect | Microsoft ile ASP.NET MVC uygulama. Identity.Web.OWIN |
| Anahtar Dosyaları |
App_Start/Startup.Auth.cs, Controllers/HomeController.cs |
Aşağıdaki komutlarla örneği kopyalayın ve çalıştırın:
git clone https://github.com/Azure-Samples/ms-identity-aspnet-webapp-openidconnect
cd ms-identity-aspnet-webapp-openidconnect
# Update Web.config with your Microsoft Entra app registration
# Run in Visual Studio
En iyi yöntemleri izleyin
Bu önerilen desenleri uygulayın ve Microsoft.Identity.Web.OWIN ile çalışırken yaygın hatalardan kaçının.
Önerilen desenleri uygulama
1. Üretimde dağıtılmış önbellek kullanın:
// Production
services.AddDistributedTokenCaches(cacheServices =>
{
cacheServices.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = ConfigurationManager.ConnectionStrings["TokenCache"].ConnectionString;
options.SchemaName = "dbo";
options.TableName = "TokenCache";
options.DefaultSlidingExpiration = TimeSpan.FromMinutes(90);
});
});
2. Artımlı onayı düzgün bir şekilde işleyin:
try
{
var graphClient = this.GetGraphServiceClient();
var user = await graphClient.Me.GetAsync();
}
catch (MsalUiRequiredException)
{
// User needs to consent to additional scopes
return new ChallengeResult();
}
3. Sorun giderme için bağıntı kimliklerini kullanın:
var downstreamApi = this.GetDownstreamApi();
var correlationId = Guid.NewGuid();
var result = await downstreamApi.GetForUserAsync<Todo>(
"TodoListService",
options =>
{
options.RelativePath = $"api/todolist/{id}";
options.TokenAcquisitionOptions = new TokenAcquisitionOptions
{
CorrelationId = correlationId
};
});
4. Uygun hata işlemeyi uygulayın:
try
{
// Call API
}
catch (MsalUiRequiredException)
{
return new ChallengeResult();
}
catch (HttpRequestException ex)
{
logger.Error($"API call failed: {ex.Message}");
return View("Error");
}
Yaygın hatalardan kaçının
1. Web grupları için bellek içi önbellek kullanmayın:
// Wrong for load-balanced scenarios
services.AddDistributedTokenCaches(cacheServices =>
{
cacheServices.AddDistributedMemoryCache();
});
// Correct
services.AddDistributedTokenCaches(cacheServices =>
{
cacheServices.AddDistributedSqlServerCache(/* ... */);
});
2. Yapılandırmayı sabit kodlamayın:
// Wrong
ClientId = "your-client-id-here"
// Correct
ClientId = ConfigurationManager.AppSettings["AzureAd:ClientId"]
3. Belirtecin süresinin dolmasını göz ardı etmeyin:
// Microsoft.Identity.Web.OWIN handles this automatically
// No manual token refresh needed!
Yaygın sorunları giderme
Kurulum ve çalışma zamanı sırasında oluşan yaygın sorunlar için aşağıdaki çözümleri gözden geçirin.
Sık karşılaşılan sorunları çözme
Sorun 1: "IAuthorizationHeaderProvider bulunamıyor"
Çözüm:OwinTokenAcquirerFactory üzerinde Startup.Auth.cs kayıtlı olduğundan emin olun.
var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
tokenAcquirerFactory.Build(serviceProvider);
app.Use<OwinTokenAcquisitionMiddleware>(tokenAcquirerFactory);
Sorun 2: "GraphServiceClient bulunamıyor"
Çözüm:AddMicrosoftGraph() ekleyin Startup.Auth.cs:
services.AddMicrosoftGraph();
Sorun 3: Belirteç önbelleği kalıcı değil
Çözüm: Dağıtılmış önbellek yapılandırmasını doğrulayın:
services.AddDistributedTokenCaches(cacheServices =>
{
cacheServices.AddDistributedSqlServerCache(options =>
{
// Ensure connection string is correct
options.ConnectionString = ConfigurationManager.ConnectionStrings["TokenCache"].ConnectionString;
});
});
İlgili içeriği keşfetme
İlgili özellikler ve senaryolar hakkında daha fazla bilgi edinin.