本文使用的授權碼模式,已更新至 .NET Core 2.2
本快速入門將展示如何構建基於瀏覽器的 JavaScript 客戶端應用程序(SPA)。
用戶將登錄 IdentityServer,使用 IdentityServer 發出的 AccessToken 調用Web API,並注銷IdentityServer。這些操作都通過 JavaScript 客戶端來執行。
添加 JavaScript 客戶端項目
為 JavaScript 客戶端應用程序創建一個新項目。它可以只是一個空的Web項目,一個空的ASP.NET Core應用程序項目,或者 Node.js 應用程序項目。本快速入門將使用ASP.NET Core 應用程序項目。
在解決方案下添加一個新的ASP.NET Core空項目。您可以使用Visual Studio或從命令行執行此操作:
md JavaScriptClient
cd JavaScriptClient
dotnet new web
修改Host地址
修改 JavaScriptClient 項目以在端口5003上運行。
添加靜態文件中間件
鑒於該項目旨在運行JavaScript客戶端,我們所需要的只是ASP.NET Core提供構成我們應用程序的靜態HTML和JavaScript文件。靜態文件中間件旨在實現此目的。
在Startup.cs中注冊靜態文件中間件Configure
(同時刪除其他所有內容):
public void Configure(IApplicationBuilder app)
{
app.UseDefaultFiles();
app.UseStaticFiles();
}
此中間件現在將從應用程序的〜/ wwwroot文件夾中提供靜態文件。這是我們將放置HTML和JavaScript文件的地方。如果項目中不存在該文件夾,請自行創建。
添加 OIDC JavaScript 客戶端
在基於ASP.NET Core MVC的客戶端項目的前一個快速入門中,我們使用OIDC組件來處理OpenID Connect協議。在 JavaScriptClient 項目中,我們需要一個類似的庫,一個基於 JavaScript 的OIDC組件。該OIDC客戶端庫就是這樣一個組件。它可以通過NPM,Bower以及從github 直接下載。
NPM
如果要使用NPM下載oidc-client,請從JavaScriptClient項目目錄運行以下命令:
npm i oidc-client
copy node_modules\oidc-client\dist\* wwwroot
這將在下載最新的oidc-client軟件包,然后將相關的JavaScript文件復制到〜/ wwwroot中,以便它們可以正常工作。
手動下載
如果您只想手動下載oidc-client JavaScript文件,請瀏覽到GitHub存儲庫 並下載JavaScript文件。下載后,將它們復制到〜/ wwwroot中,以便它們可以正常工作。
添加HTML和JavaScript文件
接下來是將您的HTML和JavaScript文件添加到〜/ wwwroot。我們將有兩個HTML文件和一個用於應用程序的JavaScript文件(除了oidc-client.js)。在〜/ wwwroot中,添加一個名為index.html和callback.html的HTML文件,並添加一個名為app.js的JavaScript文件。
index.html
這將是我們應用程序中的主頁面。它將只包含用於登錄,注銷和調用Web API的按鈕的HTML。它還將包含<script>
標記以包含我們的兩個JavaScript文件。它還將包含<pre>
用於向用戶顯示消息的用途。
它應該如下所示:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<button id="login">Login</button>
<button id="api">Call API</button>
<button id="logout">Logout</button>
<pre id="results"></pre>
<script src="oidc-client.js"></script>
<script src="app.js"></script>
</body>
</html>
app.js
這將包含我們的應用程序的主要代碼。第一件事是添加一個函數來將消息記錄到<pre>
:
function log() {
document.getElementById('results').innerText = '';
Array.prototype.forEach.call(arguments, function (msg) {
if (msg instanceof Error) {
msg = "Error: " + msg.message;
}
else if (typeof msg !== 'string') {
msg = JSON.stringify(msg, null, 2);
}
document.getElementById('results').innerHTML += msg + '\r\n';
});
}
接下來,添加代碼以將click
事件處理程序注冊到三個按鈕:
document.getElementById("login").addEventListener("click", login, false);
document.getElementById("api").addEventListener("click", api, false);
document.getElementById("logout").addEventListener("click", logout, false);
接下來,我們可以使用UserManager
類從OIDC客戶端庫來管理ID連接協議。它需要MVC Client中必需的類似配置(盡管具有不同的值)。添加此代碼以配置和實例化UserManager
:
var config = {
authority: "http://localhost:5000",
client_id: "js",
redirect_uri: "http://localhost:5003/callback.html",
response_type: "code",
scope:"openid profile api1",
post_logout_redirect_uri : "http://localhost:5003/index.html",
};
var mgr = new Oidc.UserManager(config);
接下來,UserManager
提供getUser
API以確定用戶是否登錄到JavaScript應用程序。它使用JavaScript Promise
以異步方式返回結果。返回的User
對象具有profile
包含用戶Claim的屬性。添加此代碼以檢測用戶是否已登錄JavaScript應用程序:
mgr.getUser().then(function (user) {
if (user) {
log("User logged in", user.profile);
}
else {
log("User not logged in");
}
});
接下來,我們要實現的login
,api
和logout
功能。在UserManager
提供了signinRedirect
登錄用戶,並且signoutRedirect
以注銷用戶。User
我們在上面的代碼中獲得的對象還具有access_token
可用於向Web API進行身份認證的屬性。使用access_token
包含在請求頭中發送給需要授權的API,以此來進行認證授權。添加此代碼以在我們的應用程序中實現這三個功能:
function login() {
mgr.signinRedirect();
}
function api() {
mgr.getUser().then(function (user) {
var url = "http://localhost:5001/identity";
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = function () {
log(xhr.status, JSON.parse(xhr.responseText));
}
xhr.setRequestHeader("Authorization", "Bearer " + user.access_token);
xhr.send();
});
}
function logout() {
mgr.signoutRedirect();
}
有關如何創建上述代碼中使用的api的信息,請參閱客戶端認證快速入門。
callback.html
用戶登錄IdentityServer后,將跳轉回redirect_uri
指定的頁面。它將完成與IdentityServer的OpenID Connect協議登錄握手。這個代碼全部由UserManager
我們之前使用的類提供。登錄完成后,我們可以將用戶重定向回 index.html
頁面。添加此代碼以完成登錄過程:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<script src="oidc-client.js"></script>
<script>
new Oidc.UserManager({response_mode:"query"}).signinRedirectCallback().then(function() {
window.location = "index.html";
}).catch(function(e) {
console.error(e);
});
</script>
</body>
</html>
IdentityServer 客戶端配置加入 JavaScript 客戶端
既然客戶端應用程序已經准備就緒,我們需要在IdentityServer中為這個新的JavaScript客戶端定義一個配置。在IdentityServer項目中找到客戶端配置(在Config.cs中)。將新客戶端添加到我們的客戶端列表中。它應該具有下面列出的配置:
// JavaScript Client
new Client
{
ClientId = "js",
ClientName = "JavaScript Client",
AllowedGrantTypes = GrantTypes.Code,
RequirePkce = true,
RequireClientSecret = false,
RedirectUris = { "http://localhost:5003/callback.html" },
PostLogoutRedirectUris = { "http://localhost:5003/index.html" },
AllowedCorsOrigins = { "http://localhost:5003" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api1"
}
}
使用Ajax跨域調用API
最后一點配置是在Web API項目中配置CORS。這將允許從http// localhost:5003
到http:// localhost:5001
進行Ajax跨域調用。
配置CORS
在Startup.cs ConfigureServices
中將CORS服務添加到依賴注入系統:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ApiName = "api1";
});
services.AddCors(options =>
{
// this defines a CORS policy called "default"
options.AddPolicy("default", policy =>
{
policy.WithOrigins("http://localhost:5003")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
}
將CORS中間件添加到管道中Configure
:
public void Configure(IApplicationBuilder app)
{
app.UseCors("default");
app.UseAuthentication();
app.UseMvc();
}
運行JavaScript應用程序
現在您應該能夠運行JavaScript客戶端應用程序:
單擊“Login”按鈕以對用戶進行認證。一旦用戶返回到JavaScript應用程序,您應該看到他們的個人資料信息:
然后單擊“API”按鈕以調用Web API:
最后點擊“Logout”以注銷用戶。
您現在可以開始使用IdentityServer進行登錄,注銷和驗證對Web API的調用的JavaScript客戶端應用程序。
資料
官方原文:Adding a JavaScript client
Demo: 6_JavaScriptClient