• 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与认证服务集成的方案。

    本文来自博客园,作者:寻找无名的特质,转载请注明原文链接:https://www.cnblogs.com/zhenl/p/15654284.html

  • 相关阅读:
    poj3294 Life Forms(后缀数组)
    1628. White Streaks(STL)
    1523. K-inversions(K逆序对)
    1890. Money out of Thin Air(线段树 dfs转换区间)
    1350. Canteen(map)
    1521. War Games 2(线段树解约瑟夫)
    1003. Parity(并查集)
    1470. UFOs(三维树状数组)
    1471. Tree(LCA)
    1494. Monobilliards(栈)
  • 原文地址:https://www.cnblogs.com/zhenl/p/15654284.html
Copyright © 2020-2023  润新知