zoukankan      html  css  js  c++  java
  • IdentityServer4 for ASP.NET WEB Applications (单点登录统一认证)

    服务端

    1. 新建ASP.NET Core Web MVC 项目

    SSOServer

    1. NuGet安装IdentityServer4
    2. 新建Config.cs类
        public class Config
        {
            // scopes define the resources in your system
            public static IEnumerable<IdentityResource> GetIdentityResources()
            {
                return new List<IdentityResource>
                {
                    new IdentityResources.OpenId(),
                    new IdentityResources.Profile(),
                };
            }
    
            // clients want to access resources (aka scopes)
            public static IEnumerable<Client> GetClients()
            {
                return new List<Client>
                {
                    // OpenID Connect隐式流客户端(MVC)
                    new Client
                    {
                        ClientId = "mvc",
                        ClientName = "MVC Client",
                        AllowedGrantTypes = GrantTypes.Implicit,//隐式方式
                        RequireConsent=false,//如果不需要显示否同意授权 页面 这里就设置为false
                        RedirectUris = { "http://localhost:5002/signin-oidc" },//登录成功后返回的客户端地址
                        PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },//注销登录后返回的客户端地址
    
                        AllowedScopes =//下面这两个必须要加吧 不太明白啥意思
                        {
                            IdentityServerConstants.StandardScopes.OpenId,
                            IdentityServerConstants.StandardScopes.Profile
                        }
                    }
                };
            }
        }
    
    1. Startup.cs中注入IdentityServer4
        public class Startup
        {
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            public IConfiguration Configuration { get; }
    
            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddControllersWithViews();
                // 注入IdentityServer
                services.AddIdentityServer()
                    .AddDeveloperSigningCredential()
                    .AddInMemoryIdentityResources(Config.GetIdentityResources())
                    .AddInMemoryClients(Config.GetClients());
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    app.UseExceptionHandler("/Home/Error");
                }
                app.UseStaticFiles();
    
                app.UseRouting();
    
                // 注入IdentityServer
                app.UseIdentityServer();
    
                app.UseAuthorization();
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllerRoute(
                        name: "default",
                        pattern: "{controller=Home}/{action=Index}/{id?}");
                });
            }
        }
    
    
    1. 项目属性中将调试端口改为5000
    2. 调试访问 https://localhost:5000/.well-known/openid-configuration

    能正常访问JSON即可.

    1. 增加登陆控制

    AccountController

    using Microsoft.AspNetCore.Mvc;
    using System;
    using System.Threading.Tasks;
    using IdentityServer4;
    using Microsoft.AspNetCore.Http;
    
    namespace SSOServer.Controllers
    {
        public class AccountController : Controller
        {
            /// <summary>
            /// 登录页面
            /// </summary>
            [HttpGet]
            public async Task<IActionResult> Login(string returnUrl = null)
            {
                ViewData["returnUrl"] = returnUrl;
                return View();
            }
    
            /// <summary>
            /// 登录post回发处理
            /// </summary>
            [HttpPost]
            public async Task<IActionResult> Login(string userName, string password, string returnUrl = null)
            {
                ViewData["returnUrl"] = returnUrl;
                if (userName=="test" && password=="test")
                {
                    Microsoft.AspNetCore.Authentication.AuthenticationProperties props = new Microsoft.AspNetCore.Authentication.AuthenticationProperties
                    {
                        IsPersistent = true,
                        ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromDays(1))
                    };
                    await HttpContext.SignInAsync(new IdentityServerUser(Guid.NewGuid().ToString()){DisplayName = userName},props); // 来源于Microsoft.AspNetCore.Http扩展
                    if (returnUrl != null)
                    {
                        return Redirect(returnUrl);
                    }
                    return View();
                }
                else
                {
                    return View();
                }
            }
        }
    }
    
    
    1. 登陆视图
    @{
        Layout = null;
    }
    <!DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>Login</title>
    </head>
    <body>
    <div align="center">
        <h1>统一认证登录中心</h1>
        <form action="/Account/Login" method="post">
            用户名:<input type="text" name="userName" /><br />
            密 码:<input type="password" name="password" /><input type="hidden" name="returnUrl" value="@ViewData["returnUrl"]" /> <br />
            <input type="submit" value="登录" />
        </form>
    </div>
    </body>
    </html>
    
    1. 测试登陆

    http://localhost:5000/Account/Login

    1. 可以安装Swashbuckle.AspNetCore以备调试

    swgger配置方式参考这里:
    https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-5.0&tabs=visual-studio




    客户端(Core)

    1. 新建ASP.NET Core Web MVC项目

    Core.Client

    1. NuGet安装IdentityServer4.AccessTokenValidation

    2. NuGet安装Microsoft.AspNetCore.Authentication.OpenIdConnect

    3. Startup配置

    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using System.IdentityModel.Tokens.Jwt;
    
    namespace Core.Client
    {
        public class Startup
        {
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            public IConfiguration Configuration { get; }
    
            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); // System.IdentityModel.Tokens.Jwt
    
                services.AddAuthentication(options =>
                    {
                        options.DefaultScheme = "Cookies";
                        options.DefaultChallengeScheme = "oidc";
                    })
                    .AddCookie("Cookies")
                    .AddOpenIdConnect("oidc", options =>
                    {
                        options.SignInScheme = "Cookies";
    
                        options.Authority = "http://localhost:5000";
                        options.RequireHttpsMetadata = false;
    
                        options.ClientId = "mvc";
                        options.SaveTokens = true;
                    });
    
                services.AddControllersWithViews();
    
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    app.UseExceptionHandler("/Home/Error");
                }
                app.UseStaticFiles();
    
                app.UseRouting();
    
                app.UseAuthentication(); 
    
                app.UseAuthorization();
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllerRoute(
                        name: "default",
                        pattern: "{controller=Home}/{action=Index}/{id?}");
                });
            }
        }
    }
    
    
    1. Home控制器中增加认证标识

    [Microsoft.AspNetCore.Authorization.Authorize]

    1. 调试

    这一步骤中,坑最多.
    首先,大部分新浏览器(IE除外),已经不支持SameSite=None & Secure=null的用法
    因此试用了网上的SameSiteCookiesServiceCollectionExtensions等方法都行不通
    将所有站点改为HTTPS站点后,问题解决




    客户端(Non Core)

    1. 新建ASP.NET Web MVC项目

    Web.Client

    站点属性端口改为44301

    1. 安装依赖程序包

    NuGet安装Microsoft.Owin.Host.SystemWeb
    NuGet安装Microsoft.Owin.Security.OpenIdConnect
    NuGet安装Microsoft.Owin.Security.Cookies

    1. SSOServer项目的Cofig.GetClients增加站点配置
                new Client
                    {
                        ClientName = ".NET 4 MVC website",
                        ClientId = "net4mvcclient",
                        ClientSecrets =
                        {
                            new Secret("secret3".Sha256())
                        },
    
                        AllowedGrantTypes = GrantTypes.Implicit, //隐式流
                        RequireConsent = false,
                        AllowOfflineAccess = true,
    
                        AllowAccessTokensViaBrowser = true, //To be able to get the token via browser
    
                        RedirectUris = { "https://localhost:44301/signin-oidc" },
                        PostLogoutRedirectUris = { "https://localhost:44301" }, //An existing route on MVC client
    
                        AllowedScopes = {"openid", "profile", "offline_access", "api1", "api2" }
                    },
    
    1. 配置cookie中间件

    更改 ASP.NET MVC项目的Startup类代码,将OpenID Connect中间件指向IdentityServer4实例。

    using Microsoft.Owin;
    using Microsoft.Owin.Security.Cookies;
    using Microsoft.Owin.Security.OpenIdConnect;
    using Owin;
    
    [assembly: OwinStartup(typeof(Web.Client.Startup))]
    
    namespace Web.Client
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                // 有关如何配置应用程序的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkID=316888
                app.UseCookieAuthentication(new CookieAuthenticationOptions
                {
                    AuthenticationType = "Cookies"
                });
    
                app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
                {
                    Authority = "https://localhost:5000",
                    ClientId = "net4mvcclient",
                    ClientSecret = "secret3",
                    RedirectUri = "https://localhost:44301/signin-oidc",
                    PostLogoutRedirectUri = "https://localhost:44301", //Same value as set on Config.cs on IdentityServer 
                    ResponseType = "id_token token", // to get id_token + access_token 
                    RequireHttpsMetadata = false,
                    TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                    {
                        NameClaimType = "name"
                    }, // This is to set Identity.Name 
                    SignInAsAuthenticationType = "Cookies"
                });
            }
        }
    }
    
    1. HomeController.Contact增加认证
            [Authorize]
            public ActionResult Contact()
            {
                ViewBag.Message = "Your contact page.";
    
                return View();
            }
    
    1. 调试测试

    测试登录跳转以及认证访问正常




    客户端(Wisej)

    1. 创建项目

    Wisej.Client
    创建文件夹Controllers & Views
    添加MVC5依赖项

    Visual Studio 已向项目“Wisej.Client”添加 ASP.NET MVC 5 的 全部集合 个依赖项。
    
    项目中的 Global.asax.cs 文件可能需要其他更改才能启用 ASP.NET MVC。
    
    1. 添加以下命名空间引用:
    
        using System.Web.Mvc;
        using System.Web.Routing;
        using System.Web.Optimization;
    
    2. 如果代码尚未定义 Application_Start 方法,请添加以下方法:
    
        protected void Application_Start()
        {
        }
    
    3. 在 Application_Start 方法的末尾添加以下行:
    
        AreaRegistration.RegisterAllAreas();
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    
    1. 安装依赖程序包

    NuGet安装Microsoft.AspNet.Mvc (MVC基架)
    NuGet安装Microsoft.AspNet.Web.Optimization (MVC基架)
    NuGet安装bootstrap (MVC基架)
    NuGet安装Microsoft.Owin.Host.SystemWeb
    NuGet安装Microsoft.Owin.Security.OpenIdConnect
    NuGet安装Microsoft.Owin.Security.Cookies

    1. SSOServer项目的Cofig.GetClients增加站点配置
    new Client
                    {
                        ClientName = "Wisej Client",
                        ClientId = "wisejclient",
                        ClientSecrets =
                        {
                            new Secret("secret3".Sha256())
                        },
    
                        AllowedGrantTypes = GrantTypes.Implicit, //隐式流
                        RequireConsent = false,
                        AllowOfflineAccess = true,
    
                        AllowAccessTokensViaBrowser = true, //To be able to get the token via browser
    
                        RedirectUris = {"https://localhost:44302/signin-oidc"},
                        PostLogoutRedirectUris = {"https://localhost:44302"}, //An existing route on MVC client
    
                        AllowedScopes = {"openid", "profile", "offline_access", "api1", "api2"}
                    },
    
    1. 配置cookie中间件
    using Microsoft.Owin;
    using Microsoft.Owin.Security.Cookies;
    using Microsoft.Owin.Security.OpenIdConnect;
    using Owin;
    
    [assembly: OwinStartup(typeof(Wisej.Client.Startup))]
    
    namespace Wisej.Client
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                // 有关如何配置应用程序的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkID=316888
                app.UseCookieAuthentication(new CookieAuthenticationOptions
                {
                    AuthenticationType = "Cookies"
                });
    
                app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
                {
                    Authority = "https://localhost:5000",
                    ClientId = "wisejclient",
                    ClientSecret = "secret3",
                    RedirectUri = "https://localhost:44302/signin-oidc",
                    PostLogoutRedirectUri = "https://localhost:44302", //Same value as set on Config.cs on IdentityServer 
                    ResponseType = "id_token token", // to get id_token + access_token 
                    RequireHttpsMetadata = false,
                    TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                    {
                        NameClaimType = "name"
                    }, // This is to set Identity.Name 
                    SignInAsAuthenticationType = "Cookies"
                });
            }
        }
    }
    
    
    1. RouteConfig兼容配置
    using System.Web.Mvc;
    using System.Web.Routing;
    
    namespace Wisej.Client
    {
        public class RouteConfig
        {
            public static void RegisterRoutes(RouteCollection routes)
            {
                routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
                routes.IgnoreRoute("{resource}.html/{*pathInfo}");
                routes.IgnoreRoute("{resource}.wx/{*pathInfo}");
                routes.IgnoreRoute("{resource}.json");
    
                routes.MapRoute(
                    name: "Default",
                    url: "{controller}/{action}/{id}",
                    defaults: new { action = "Index", id = UrlParameter.Optional }
                );
            }
        }
    }
    
    
    1. 实现统一登录认证

    如果SSOServer没启动,将出现下以下错误.

    “/”应用程序中的服务器错误。 
    由于目标计算机积极拒绝,无法连接。 127.0.0.1:5000
    说明: 执行当前 Web 请求期间,出现未经处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。
    
    异常详细信息: System.Net.Sockets.SocketException: 由于目标计算机积极拒绝,无法连接。 127.0.0.1:5000
    

    或者

    “/”应用程序中的服务器错误。 
    由于意外的数据包格式,握手失败。
    说明: 执行当前 Web 请求期间,出现未经处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。
    
    异常详细信息: System.IO.IOException: 由于意外的数据包格式,握手失败。
    
    源错误:
    执行当前 Web 请求期间生成了未经处理的异常。可以使用下面的异常堆栈跟踪信息确定有关异常原因和发生位置的信息。
    
    1. 调试测试

    登录认证成功

  • 相关阅读:
    obs问题记录
    树莓派数字识别相关资料
    Focus Event
    跨浏览器的事件对象
    浅谈Javascript事件模拟
    浅谈Javascript鼠标和滚轮事件
    UI Events
    IE事件对象(The Internet Explorer Event Object)
    eclipse 调试nodejs 发生Failed to connect to standalone V8 VM错误的解决方案
    关于couldn't connect to server 127.0.0.1 shell/mongo.js:84 exception: connect failed 问题
  • 原文地址:https://www.cnblogs.com/honk/p/14525837.html
Copyright © 2011-2022 走看看