我即将在 Azure 中托管在 .NET 4.8 上运行的现有 ASP.NET MVC 应用程序。我想使用 Azure AD (Azure Identity) 实施身份验证。
我正在寻找一些快速入门或演练,但找不到我一年前找到的内容。有人可以帮助我执行一些步骤,以便我可以让我的应用程序使用 Azure AD 身份验证吗?
谢谢
我使用下面的代码为 ASP.NET MVC .NET 4.8 应用程序实现 AzureAD。
我在controller文件夹中创建了一个Account Controller,如下图。
帐户控制器:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Microsoft.Owin.Security;
namespace MvcWithAzureAd123.Controllers
{
public class AccountController : Controller
{
public void SignIn()
{
if (!Request.IsAuthenticated)
{
HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/" },
OpenIdConnectAuthenticationDefaults.AuthenticationType);
}
}
public void SignOut()
{
string callbackUrl1 = Url.Action("SignOutCallback", "Account", routeValues: null, protocol: Request.Url.Scheme);
HttpContext.GetOwinContext().Authentication.SignOut(
new AuthenticationProperties { RedirectUri = callbackUrl },
OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType);
}
public ActionResult SignOutCallback()
{
if (Request.IsAuthenticated)
{
return RedirectToAction("Index", "Home");
}
return View();
}
}
}
我将 Startup.Auth.cs 类添加到我的 App_Start 文件夹中。
App_Start/Startup.Auth.cs:
using System;
using System.Configuration;
using System.Security.Claims;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;
namespace MvcWithAzureAd123
{
public partial class Startup
{
private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private static string aadInstance = EnsureTrailingSlash(ConfigurationManager.AppSettings["ida:AADInstance"]);
private static string tenantId = ConfigurationManager.AppSettings["ida:TenantId"];
private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
private static string authority = aadInstance + tenantId + "/v2.0";
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = postLogoutRedirectUri,
Notifications = new OpenIdConnectAuthenticationNotifications()
{
SecurityTokenValidated = (context) =>
{
string name = context.AuthenticationTicket.Identity.FindFirst("preferred_username").Value;
context.AuthenticationTicket.Identity.AddClaim(new Claim(ClaimTypes.Name, name, string.Empty));
return System.Threading.Tasks.Task.FromResult(0);
}
}
});
}
private static string EnsureTrailingSlash(string value)
{
if (value == null)
{
value = string.Empty;
}
if (!value.EndsWith("/", StringComparison.Ordinal))
{
return value + "/";
}
return value;
}
}
}
我在我的Azure帐户中创建了一个应用程序注册,如下所示:
我在 web.config 中添加了 ClientId、TenantId 和 dependentAssembly,如下所示。
web.config:
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="ida:ClientId" value="<ClientId>" />
<add key="ida:AADInstance" value="https://login.microsoftonline.com/" />
<add key="ida:Domain" value="microsoft.onmicrosoft.com" />
<add key="ida:TenantId" value="<TenanatId>" />
<add key="ida:PostLogoutRedirectUri" value="https://<URL>/signin-oidc" />
</appSettings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Tokens" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Protocols.OpenIdConnect" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Protocols" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Protocol.Extensions" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-1.0.40306.1554" newVersion="1.0.40306.1554" />
</dependentAssembly>
<---------Other dependentAssembly-------->
</runtime>
我在根目录中添加了一个 Startup.cs 类。
Startup.cs:
using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;
namespace MvcWithAzureAd123
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
}
}
然后,我在Shared文件夹中实现了_loginPartial.cshtml视图,如下所示。
共享/_LoginPartial.cshtml:
@if (Request.IsAuthenticated)
{
<text>
<ul class="navbar-nav navbar-right">
<li class="navbar-text">
Hello, @User.Identity.Name!
</li>
<li>
@Html.ActionLink("Sign out", "SignOut", "Account", new { area = "" }, new { @class = "nav-link" })
</li>
</ul>
</text>
}
else
{
<ul class="navbar-nav navbar-right">
<li>@Html.ActionLink("Sign in", "SignIn", "Account", routeValues: null, htmlAttributes: new { id = "loginLink", @class = "nav-link" })</li>
</ul>
}
我将signoutcallback.cshtml视图添加到View文件夹中的Account文件夹中以用于注销目的。
查看/帐户/SignOutCallback.cshtml:
@{
ViewBag.Title = "Sign Out";
}
<main aria-labelledby="title">
<h2 id="title">@ViewBag.Title.</h2>
<p class="text-success">You have successfully signed out.</p>
</main>
我向控制器添加了
[Authorize]
属性,如下所示。
家庭控制器:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcWithAzureAd123.Controllers
{
[Authorize]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
}
这是我的Package.config,我下载了需要的NuGet包,如下图。
package.config:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Antlr" version="3.5.0.2" targetFramework="net48" />
<package id="bootstrap" version="5.2.3" targetFramework="net48" />
<package id="jQuery" version="3.4.1" targetFramework="net48" />
<package id="jQuery.Validation" version="1.17.0" targetFramework="net48" />
<package id="Microsoft.AspNet.Mvc" version="5.2.9" targetFramework="net48" />
<package id="Microsoft.AspNet.Razor" version="3.2.9" targetFramework="net48" />
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net48" />
<package id="Microsoft.AspNet.WebPages" version="3.2.9" targetFramework="net48" />
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.1" targetFramework="net48" />
<package id="Microsoft.IdentityModel.JsonWebTokens" version="5.5.0" targetFramework="net48" />
<package id="Microsoft.IdentityModel.Logging" version="5.5.0" targetFramework="net48" />
<package id="Microsoft.IdentityModel.Protocol.Extensions" version="1.0.4.403061554" targetFramework="net48" />
<package id="Microsoft.IdentityModel.Protocols" version="5.5.0" targetFramework="net48" />
<package id="Microsoft.IdentityModel.Protocols.OpenIdConnect" version="5.5.0" targetFramework="net48" />
<package id="Microsoft.IdentityModel.Tokens" version="5.5.0" targetFramework="net48" />
<package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.2.11" targetFramework="net48" />
<package id="Microsoft.Owin" version="4.2.2" targetFramework="net48" />
<package id="Microsoft.Owin.Host.SystemWeb" version="4.2.2" targetFramework="net48" />
<package id="Microsoft.Owin.Security" version="4.2.2" targetFramework="net48" />
<package id="Microsoft.Owin.Security.Cookies" version="4.2.2" targetFramework="net48" />
<package id="Microsoft.Owin.Security.OpenIdConnect" version="4.2.2" targetFramework="net48" />
<package id="Microsoft.Web.Infrastructure" version="2.0.1" targetFramework="net48" />
<package id="Modernizr" version="2.8.3" targetFramework="net48" />
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net48" />
<package id="Owin" version="1.0" targetFramework="net48" />
<package id="System.IdentityModel.Tokens.Jwt" version="5.5.0" targetFramework="net48" />
<package id="WebGrease" version="1.6.0" targetFramework="net48" />
</packages>
我在应用程序注册中添加了重定向 URL,
https://localhost:Port/signin-oidc
,如下所示:
运行应用程序后,它要求我选择一个帐户,如下所示:
它要求我接受应用程序注册。
输出:
在将应用程序发布到 Azure 之前,请在 web.config 中将 PostLogoutRedirectUri 值更改为
https://<AzureWebAppName>.azurewebsites.net/.auth/login/aad/callback
。
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="ida:ClientId" value="<ClientId>" />
<add key="ida:AADInstance" value="https://login.microsoftonline.com/" />
<add key="ida:Domain" value="microsoft.onmicrosoft.com" />
<add key="ida:TenantId" value="<TenanatId>" />
<add key="ida:PostLogoutRedirectUri" value="https://kamvcwithazuread.azurewebsites.net/.auth/login/aad/callback" />
</appSettings>
我在 Azure Web 应用程序中添加了身份提供程序,如下所示:
我选择身份提供商 Microsoft 并添加了我的应用程序注册。
已成功添加到Web App,如下图:
然后,我将重定向 URI
https://<WebAppName>.azurewebsites.net/.auth/login/aad/callback
添加到我的应用程序注册中。
Azure 应用服务输出: