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. 调试测试

登录认证成功

原文地址:https://www.cnblogs.com/honk/p/14525837.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


数组的定义 Dim MyArray MyArray = Array(1‚5‚123‚12‚98) 可扩展数组 Dim MyArray() for i = 0 to 10
\'参数: \'code:要检测的代码 \'leixing:html或者ubb \'nopic:代码没有图片时默认值
演示效果: 代码下载: 点击下载
环境:winxp sp2 ,mysql5.0.18,mysql odbc 3.51 driver 表采用 myisam引擎。access 2003  不同的地方: 
其实说起AJAX的初级应用是非常简单的,通俗的说就是客户端(javascript)与服务端(asp或php等)脚本语言的数据交互。
<% ’判断文件名是否合法 Function isFilename(aFilename)  Dim sErrorStr,iNameLength,i  isFilename=TRUE
在调用的时候加入判断就行了. {aspcms:navlist type=0 } {if:[navlist:i]<6} < li><a href=\"[navlist:link]\" target=\"_top\">[navlist:name]</a> </li>
导航栏调用 {aspcms:navlist type=0}     <a href=\"[navlist:link]\">[navlist:name]</a>
1.引入外部文件: {aspcms:template src=infobar.html} 2.二级下拉菜单 <ul class=\"nav\">
downpic.asp页面:  <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
Cookies是数据包,可以让网页具有记忆功能,在某台电脑上记忆一定的信息。Cookies的工作原理是,第一次由服务器端写入到客户端的系统中。以后每次访问这个网页,都是先由客户端将Cookies发送到服务器端,再由服务器端
很简单,在需要调用的地方用这种模式 {aspcms:content sort={aspcms:sortid} num=17 order=isrecommend}
网站系统使用ACCESS数据库时,查询时怎么比较日期和时间呢?为什么常常比较出来却是错误的呢?比如早的日期比迟的日期大?
str1=\"1235,12,23,34,123,21,56,74,1232\" str2=\"12\" 问题:如何判断str2是否存在str1中,要求准确找出12,不能找出str1中的1235、123、1232
实例为最新版本的kindeditor 4.1.5. 主要程序: <% Const sFileExt=\"jpg|gif|bmp|png\" Function ReplaceRemoteUrl(sHTML,sSaveFilePath,sFileExt)
用ASP实现搜索引擎的功能是一件很方便的事,可是,如何实现类似3721的智能搜索呢?比如,当在搜索条件框内输入“中国人民”时,自动从中提取“中国”、“人民”等关键字并在数据库内进行搜索。看完本文后,你就可以发
首先感谢ASPCMS官网注册用户xing0203的辛苦付出!一下为久忆YK网络转载原创作者xing0203的文章内容!为了让小白更加清楚的体验替换过程,久忆YK对原文稍作了修改!
数据库连接: <% set conn=server.createobject(\"adodb.connection\") conn.open \"driver={microsoft access driver (*.mdb)};dbq=\"&server.mappath(\"数据库名\")
第1步:修改plugins下的image/image.js 找到\'<input type=\"button\" class=\"ke-upload-button\" value=\"\' + lang.upload + \'\" />\',
asp函数: <% Const sFileExt=\"jpg|gif|bmp|png\" Function ReplaceRemoteUrl(sHTML,sSaveFilePath,sFileExt)