在咱们的案例中,咱们是用户经过Web应用程序进行身份识别。html
上面的图示说明了以下的一些概念web
l Azure AD 是标识提供程序,负责对组织的目录中存在的用户和应用程序的标识进行验证,并最终在那些用户和应用程序成功经过身份验证时颁发安全令牌。api
l 但愿将身份验证外包给 Azure AD 的应用程序必须在 Azure AD 中进行注册,Azure AD 将在目录中注册并惟一地标识该应用程序。安全
l 在用户经过身份验证后,应用程序必须对用户的安全令牌进行验证以确保身份验证对于目标方是成功的。架构
l 身份验证过程的请求和响应流是由所使用的身份验证协议(例如 OAuth 2.0、OpenID Connect、WS-Federation 或 SAML 2.0)决定的app
这章咱们将简单的对Azure AD的开发进行入门性的尝试,包括身份验证登陆、基自己份信息的存储。要完成Azure AD的应用开发须要在Azure门户和开发环境中各自完成一些工做。async
Azure AD开发部分ide
首先咱们须要引入如下组件库ui
Microsoft.IdentityModel.Clients.ActiveDirectory
Microsoft.IdentityModel.Protocol.Extensions
Microsoft.Owin
Microsoft.Owin.Host.SystemWeb
Microsoft.Owin.Security
Microsoft.Owin.Security.Cookies
Microsoft.Owin.Security.OpenIdConnect
Microsoft.Web.Infrastructure
Microsoft.WindowsAzure.ConfigurationManager.
System.IdentityModel.Tokens.Jwt
<ADD KEY="IDA:CLIENTID" VALUE=" " /> <ADD KEY="IDA:TENANT" VALUE=" " /> <ADD KEY="IDA:TENANTID" VALUE="" /> <ADD KEY="IDA:AADINSTANCE" VALUE="HTTPS://LOGIN.CHINACLOUDAPI.CN/{0}" /> <ADD KEY="IDA:POSTLOGOUTREDIRECTURI" VALUE=" " /> <ADD KEY="IDA:GRAPHURL" VALUE="HTTPS://GRAPH.CHINACLOUDAPI.CN" /> <ADD KEY="IDA:APPKEY" VALUE="" />
而后咱们须要编写AuthenticationHelper类来辅助咱们处理有关受权的基本处理,AuthenticationHelper有两大部分,第一部分是经过静态字段来读取在Web.config文件的appSettings节配置的有关Azure AD的信息。spa
public static readonly string Tenant = CloudConfigurationManager.GetSetting("ida:Tenant"); public static readonly string TenantId = CloudConfigurationManager.GetSetting("ida:TenantId"); public static readonly string LoginUrl = CloudConfigurationManager.GetSetting("ida:AADInstance"); public static readonly string GraphUrl = CloudConfigurationManager.GetSetting("ida:GraphUrl"); public static readonly string AppKey = CloudConfigurationManager.GetSetting("ida:AppKey"); public static readonly string AuthorityUrl = String.Format(CultureInfo.InvariantCulture, LoginUrl, TenantId); public static readonly string AuthString = CloudConfigurationManager.GetSetting("ida:Auth") + CloudConfigurationManager.GetSetting("ida:Tenant"); public static readonly string ClaimsSchemas = "http://schemas.microsoft.com/identity/claims/objectidentifier"; public static readonly string ClientId = CloudConfigurationManager.GetSetting("ida:ClientId"); public static readonly string ClientSecret = CloudConfigurationManager.GetSetting("ida:ClientSecret"); public static readonly string PostLogoutRedirectUri = CloudConfigurationManager.GetSetting("ida:PostLogoutRedirectUri");
而后在AuthenticationHelper中添加一个方法AcquireTokenAsync,这个方法用于返回当前的用户凭证,若是没有凭证则抛出异常。
public static string Token; public static async Task<string> AcquireTokenAsync() { if (Token == null || Token.IsEmpty()) { throw new Exception("Authorization Required."); } return Token; }
public static ActiveDirectoryClient GetActiveDirectoryClient() { Uri baseServiceUri = new Uri(GraphUrl); ActiveDirectoryClient activeDirectoryClient = new ActiveDirectoryClient(new Uri(baseServiceUri, TenantId), async () => await AcquireTokenAsync()); return activeDirectoryClient; }
SignIn
SignOut
SignIn登陆
代码很是简单,在当前上下文的采用OpenID进行身份询问获取
public void SignIn() { if (!Request.IsAuthenticated) { HttpContext.GetOwinContext() .Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectAuthenticationDefaults.AuthenticationType); } }
SignOut登出
一样代码简单明确
public void SignOut() { string userObjectID = ClaimsPrincipal.Current.FindFirst(AuthenticationHelper.ClaimsSchemas).Value; var authContext = new AuthenticationContext(AuthenticationHelper.AuthorityUrl, new NaiveSessionCache(userObjectID)); authContext.TokenCache.Clear(); AuthenticationHelper.Token = null; HttpContext.GetOwinContext().Authentication.SignOut(OpenIdConnectAuthenticationDefaults.AuthenticationType, CookieAuthenticationDefaults.AuthenticationType); }
@if (Request.IsAuthenticated) { <text> <ul class="nav navbar-nav navbar-right"> <li class="navbar-text"> Hello, @User.Identity.Name! </li> <li> @Html.ActionLink("Sign out", "SignOut", "AzureActiveDirectory") </li> </ul> </text> } else { <ul class="nav navbar-nav navbar-right"> <li>@Html.ActionLink("Sign in", "SignIn", "AzureActiveDirectory", routeValues: null, htmlAttributes: new { id = "loginLink" })</li> </ul> }
上面的代码经过一个if完成登录后出现Sign out连接和登出状态为Sign in连接。而后在View\ Shared\ _LoginPartial.cshtml加入这个_LoginPartial.cshtml咱们就在主模板拥有了登陆登出的连接功能。我对_LoginPartial.cshtml此处的修改以下
<div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li>@Html.ActionLink("主页", "Index", "Home")</li> <li>@Html.ActionLink("关于", "About", "Home")</li> <li>@Html.ActionLink("联系方式", "Contact", "Home")</li> </ul> @Html.Partial("_LoginPartial") </div>
如今咱们执行代码后,咱们看到的默认页面是
点击Sign in连接后将跳转到微软的登陆界面
点击帐号后
输入正确的密码后,将跳回咱们应用的默认首页,而且明显的发现咱们已经使用了正确的身份登入了。