前面的部分:
Identity Server 4 從入門到落地(一)—— 從IdentityServer4.Admin開始
Identity Server 4 從入門到落地(二)—— 理解授權碼模式
Identity Server 4 從入門到落地(三)—— 建立Web客戶端
Identity Server 4 從入門到落地(四)—— 建立Web Api
Identity Server 4 從入門到落地(五)—— 使用Ajax 訪問 Web Api
Identity Server 4 從入門到落地(六)—— 簡單的單頁面客戶端
Identity Server 4 從入門到落地(七)—— 控制檯客戶端
認證服務和管理的github地址: https://github.com/zhenl/IDS4Admin
客戶端及web api示例程式碼的github地址:https://github.com/zhenl/IDS4ClientDemo
在面向企業的資訊化專案中,很少有專案是從一張白紙開始,或多或少都要面臨與現有專案整合或者遺留專案升級與整合的問題,認證服務的使用更是如此,各種現有系統的單點登入就是認證服務常用的場景之一,因此,如果遺留系統無法使用,那麼這個技術在專案中就無法落地使用。現實中仍然存在大量在用的基於.Net Framework的專案,我們需要為這些專案制訂與認證服務整合的方案。我們通過建立一個.Net Framework 4.5.2的簡單應用來驗證方案的可行性,主要使用的技術是採用Owin實現OpenIdConnect的客戶端,構建過程如下。
首先,在我們現有的測試解決方案中增加一個Asp.Net MVC專案,採用.Net Framework 4.5.2框架,專案名稱為IDS4ClientNet4。
然後,在專案中引入如下程式包:
IdentityModel
Microsoft.Owin
Microsoft.Owin.Host.SystemWeb
接下來,在專案中增加Startup.cs檔案,程式碼如下:
using IDS4ClientNet4;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
[assembly: OwinStartup(typeof(Startup))]
namespace IDS4ClientNet4
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Authority = "http://localhost:4010",
ClientId = "net4mvcclient",
ClientSecret = "secret3",
RedirectUri = "http://localhost:49816/signin-oidc",//Net4MvcClient's URL
PostLogoutRedirectUri = "http://localhost:49816",
ResponseType = "id_token token",
RequireHttpsMetadata = false,
Scope = "openid profile myapi",
TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
NameClaimType = "name"
},
SignInAsAuthenticationType = "Cookies",
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = n =>
{
n.AuthenticationTicket.Identity.AddClaim(new Claim("access_token", n.ProtocolMessage.AccessToken));
n.AuthenticationTicket.Identity.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
return Task.FromResult(0);
},
RedirectToIdentityProvider = n =>
{
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
{
var id_token_claim = n.OwinContext.Authentication.User.Claims.FirstOrDefault(x => x.Type == "id_token");
if (id_token_claim != null)
{
n.ProtocolMessage.IdTokenHint = id_token_claim.Value;
}
}
return Task.FromResult(0);
}
}
});
}
}
}
注意,這裡使用的ResponseType是id_token token,不是code。
修改HomeController,將About設定為[Authorize],增加訪問WebApi和Logout功能:
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
namespace IDS4ClientNet4.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[Authorize]
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public async Task<ActionResult> WebApi()
{
var user = User as ClaimsPrincipal;
var accessToken = user.FindFirst("access_token").Value;
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var response = await client.GetAsync("http://localhost:5153/WeatherForecast");
string content;
if (!response.IsSuccessStatusCode)
{
content = await response.Content.ReadAsStringAsync();
ViewBag.Json = content;
}
else
{
content = await response.Content.ReadAsStringAsync();
ViewBag.Json = JArray.Parse(content).ToString();
}
return View();
}
public ActionResult Logout()
{
System.Web.HttpContext.Current.GetOwinContext().Authentication.SignOut();
return Redirect("/");
}
}
}
About的檢視About.cshtml如下:
@using System.Security.Claims;
@{
ViewBag.Title = "About";
}
<h2>@ViewBag.Title.</h2>
<h3>@ViewBag.Message</h3>
<p>Use this area to provide additional information.</p>
<dl>
@foreach (var claim in (User as ClaimsPrincipal).Claims)
{
<dt>@claim.Type</dt>
<dd>@claim.Value</dd>
}
</dl>
檢視WebApi.cshtml如下:
<pre>@ViewBag.Json</pre>
下面需要使用認證管理應用增加一個客戶端,名稱為net4mvcclient,Client Secret為secret3。需要注意的是,這個客戶端需要設定為隱式模式(Implicit)
設定完成後,將解決方案的啟動專案設定為多專案啟動,同時啟動客戶端和Web Api:
啟動專案,訪問關於頁面,會跳轉到認證服務的登入頁面,登入完成後,會顯示使用者的詳細資訊。訪問WebApi頁面,可以獲取Api返回的資料:
通過這個專案我們驗證了.Net Framework與認證服務整合的方案。