zoukankan      html  css  js  c++  java
  • 4. 使用IdentityServer4 实现 基于OIDC 的内部MVC客户端认证

    1. 概述

    • 上一个实例 中实现了简单的 ResourceOwnerPassword 授权.

    • 本例将使用IdentityServer4 实现内部系统的单点登录,让组织内部的MVC 客户端使用认证中心的登录页实现登录,使用的是OAuth2 的隐式授权码模式Implicit AthorizationCode

    • MVC 客户端集成IdentityServer4 认证时,为简单起见,将使用cookie存储客户端凭据;同时启用IdentityServer4 内置的 OpenIdConnect(OIDC)身份认证服务。

    2. 关键概念

    • IdentityResource : OIDC 协议中定义的身份认证资源,这种资源具有唯一名称,资源声明后将包含在用户的身份令牌中。参考: https://docs.identityserver.io/en/3.1.0/topics/resources.html

    • IIdentityServerInteractionService : 这是IdentityServer4提供的认证交互接口。

    3. 准备MVC Web客户端

    新建一个MVCClient 项目,设置访问地址和端口为:http://localhost:5030。
    

    3.1 引用依赖包

     <PackageReference Include="IdentityServer4" Version="4.1.1" />
    

    3.2 注册OIDC 服务,并启用认证中间件

    // DI容器中注册服务
    services.AddAuthentication(opt =>
                {
                    opt.DefaultScheme = "Cookies";
                    opt.DefaultChallengeScheme = "oidc";
                }).AddCookie("Cookies")
                .AddOpenIdConnect("oidc", options =>
                {
                    options.SignInScheme = "Cookies";
                    options.Authority = "http://localhost:5010";
                    options.RequireHttpsMetadata = false;
    
                    options.ClientId = "mvc";
                    options.SaveTokens = true;
                });
    
    // ConfigureService 中启用中间件
                app.UseAuthentication();
    
    // 将受保护页面使用【Authorize】 保护起来,访问首页时将重定向到Account/Login
     [Authorize]
        public class HomeController : Controller
    {
    ……  ……
    }
    

    4. 服务端配置

    4.1 添加IdentityResource(在server端的Config 类中添加) 和client

            public static List<IdentityResource> GetIdentityResources()
            {
                var result = new List<IdentityResource>
                {
                    new IdentityResources.OpenId(),
                    new IdentityResources.Profile()
                };
                return result;
            }
    
    // 新增一个client
               new Client
                {
                    ClientId="mvc",
                    ClientName="MVC Client",
                    RequireConsent=false,
                    AllowedGrantTypes= GrantTypes.Implicit, // 隐式授权码
                    RedirectUris={"http://localhost:5030/signin-oidc"}, // 这里的回调地址是MVC客户端的地址
                    PostLogoutRedirectUris={"http://localhost:5030/signout-callback-oidc"},
                    AllowedScopes= new List<string>
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile
                    }
    
                }
    
    // Startup 注册IdentityResource
    
    services.AddIdentityServer()
                    .AddDeveloperSigningCredential()
                    .AddInMemoryApiResources(Config.GetApiResources)
                    .AddInMemoryIdentityResources(Config.GetIdentityResources())
                    .AddInMemoryClients(Config.GetClients)
                    .AddInMemoryApiScopes(Config.GetApiScopes) // 3.1 新增的坑,不加会报invalid_scope
                    .AddTestUsers(Config.GetTestUsers())
                    ;
    
    

    5. 测试验证

    启动服务端5010,和客户端5030 此时客户端将重定向到5010 的登录页Account/Login

    可以输入TestUsers中配置的用户名密码登录

    5.1 Account/Login 的登录方法

           [HttpPost]
            public async Task<IActionResult> Login(LoginViewModel model, string returnUrl)
            {
                ViewData["ReturnUrl"] = returnUrl;
                var user = _users.FindByUsername(model.UserName);
    
                if (user == null)
                {
                    ModelState.AddModelError(nameof(model.UserName), "User not exists.");
                }
                else
                {
                    if (_users.ValidateCredentials(model.UserName, model.Password))
                    {
                        var props = new AuthenticationProperties
                        {
                            IsPersistent = true,
                            ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromMinutes(30))
                        };
                        var u = new IdentityServerUser(user.SubjectId) { DisplayName = user.Username };
    
                        await Microsoft.AspNetCore.Http.AuthenticationManagerExtensions.SignInAsync(
                              this.HttpContext,
                              u,
                              props);
                        return Redirect(returnUrl);
                    }
                }
                return View();
    
            }
    
  • 相关阅读:
    88. Merge Sorted Array
    87. Scramble String
    86. Partition List
    85. Maximal Rectangle
    84. Largest Rectangle in Histogram
    83. Remove Duplicates from Sorted List
    82. Remove Duplicates from Sorted List II
    81. Search in Rotated Sorted Array II
    80. Remove Duplicates from Sorted Array II
    计算几何——点线关系(叉积)poj2318
  • 原文地址:https://www.cnblogs.com/aimigi/p/13943748.html
Copyright © 2011-2022 走看看