Identity Server 4 從入門到落地(八)—— .Net Framework 客戶端


前面的部分:
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與認證服務集成的方案。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM