• <六>OIDC 客户端的引用服务端登录页面的实现


    上一节服务端已经弄好了,那么我们来创建一个mvc客户端,访问客户端的时候直接调用服务端的登录页面实现登录。

    1、创建一个mvcclient, 端口默认为5004。

    startup类中的 ConfigureServices函数总中加入认证配置

     public void ConfigureServices(IServiceCollection services)
            {
                services.AddAuthentication(options =>
                {
                    options.DefaultScheme = "Cookies";
                    options.DefaultChallengeScheme = "oidc";
                })
                .AddCookie("Cookies")
                .AddOpenIdConnect("oidc", options =>
                {
                    options.SignInScheme = "Cookies";
                    options.Authority = "http://localhost:5003";//identity服务器域名
                    options.RequireHttpsMetadata = false;       //没有证书啥的不需要传
    
                    options.ClientId = "myself";                   //MVC服务端配置的clientId 
                    options.ClientSecret = "secret";
                    options.SaveTokens = true;         
                });
                services.AddControllersWithViews();
            }

    config中加入

       app.UseAuthentication();
       app.UseAuthorization();

    默认的Homecontroller上面加上认证特性[Authorize]

    这样客户端的配置就可以了。

    2、修改一下服务端的代码

    2.1、修改login前端,新增接收回调链接的参数

    @{
    
        ViewData["Title"] = "登录";
    
    }
    
    
    
    <h2 style="text-align:center">登录管理系统</h2>
    
    
    
    <hr />
    
    <div>
    
        <form asp-controller="Account" asp-action="Login" method="post">
    
            <div>
    
                <label class="control-label">用户名</label>
    
                <input class="form-control" type="text" name="username" />
    
            </div>
    
            <div>
    
                <label class="control-label">密码</label>
    
                <input class="form-control" type="password" name="password" />
    
            </div>
    
            <div class="form-group">
    
                <input type="submit" value="登录" class="btn btn-primary" />
    
            </div>
            <input type="text" class="form-control" id="returnUrl" name="returnUrl" value="@ViewData["Rurl"]" />
        </form>
    
    </div>

    2.2、修改controller中的登录逻辑

     public class AccountController : Controller
        {
            private readonly TestUserStore _testUserStore;
         
            public AccountController( TestUserStore testUserStore)
            {
                _testUserStore = testUserStore;
            
            }
            public IActionResult Index()
            {
                return View();
            }
    
            public IActionResult Login(string returnUrl = "/Home/Index")
            {
                ViewData["Rurl"] = returnUrl;
                return View();
            }
    
            /// <summary>
            /// post 登录请求
            /// </summary>
            /// <returns></returns>
            [HttpPost]
            public async Task<IActionResult> Login(string userName, string password,string returnUrl)
            {
                if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
                {
                    return Json(new { result = false, msg = "用户名或者密码不能为空!" });
                }
                var user = _testUserStore.FindByUsername(userName);
                if (user == null)
                {
                    return Json(new { result = false, msg = "用户不存在!" });
                }
                if (_testUserStore.ValidateCredentials(userName, password))
                {
                    var props = new AuthenticationProperties
                    {
                        IsPersistent = true,
                        ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromMinutes(3))
                    };
    
                    await AuthenticationManagerExtensions.SignInAsync(
                        HttpContext,
                        new IdentityServerUser(user.SubjectId),
                        props
                        );
                    return Redirect(returnUrl);
                }
                return Json(new { result = false, msg = "用户名密码错误!" });
            }
    
        
        }

    2.3、修改identity 中的配置 config.cs

     public static class Config
        {
            public static IEnumerable<ApiScope> GetScopes()
            {
                return new ApiScope[]
                  {
                    new ApiScope("api1scope"),
                    new ApiScope("api2scope"),
                      //new ApiScope("scope2"),
                  };
            }
            // 这个 Authorization Server 保护了哪些 API (资源)
            public static IEnumerable<ApiResource> GetApiResources()
            {
                return new[]
                {
                        new ApiResource("api", "My API")
                        {
                            Scopes = { "api1scope", "api2scope" }
                        }
    
                    };
            }
    
            public static IEnumerable<IdentityResource> GetIdentityResources()
            {
                return new List<IdentityResource>
                {
                    new IdentityResources.OpenId(),
                    new IdentityResources.Profile(),
                    new IdentityResources.Email(),
                 };
            }
    
            // 哪些客户端 Client(应用) 可以使用这个 Authorization Server
            public static IEnumerable<Client> GetClients()
            {
                return new[]
                {
                        new Client
                        {
                            ClientId = "myself",//定义客户端 Id
                            ClientSecrets = new [] { new Secret("secret".Sha256()) },//Client用来获取token
                            AllowedGrantTypes = GrantTypes.Implicit,//隐式流程
    
                            RequireConsent=false,
                            RedirectUris={"http://localhost:5004/signin-oidc"},//这个在identity的地址中是固定的,登录成功回调处理地址,处理回调返回的数据
                            
                            PostLogoutRedirectUris = { "http://localhost:5004/signout-callback-oidc" },//退出的时候会返回到这个地址
    
                            AllowedScopes =  {
                                IdentityServerConstants.StandardScopes.Profile,
                                 IdentityServerConstants.StandardScopes.OpenId,
                               }// 允许访问的 API 资源
                        }
                    };
            }
    
    
    
            //测试用户
            public static IEnumerable<TestUser> GetUsers()
            {
                return new[]
                {
                        new TestUser
                        {
                            SubjectId = "1",
                            Username = "myname",
                            Password = "password"
                        }
                };
            }
        }

    2.4、在服务端startup中引用配置

      public void ConfigureServices(IServiceCollection services)
            {
                services.AddIdentityServer().AddDeveloperSigningCredential()
                    .AddInMemoryApiResources(Config.GetApiResources())
                    .AddInMemoryApiScopes(Config.GetScopes())
                    .AddInMemoryClients(Config.GetClients())
                    .AddTestUsers(Config.GetUsers().ToList())
                    .AddInMemoryIdentityResources(Config.GetIdentityResources());
                services.AddControllersWithViews();
            }


    3、运行服务端和客户端,浏览器访问localhost:5004 就会跳到登录页面,如下图所示,这里我把returnurl给显示出来了。

     4、输入用户名和密码,即使服务端config.cs里面TestUser配置的用户名和密码登录后就自动跳转到client 端口5004的主页面

    异常1、 如果客户端没有加上 app.UseAuthentication(); 的话会报signin-oidc 的页面404的情况,也就说明了UseAuthentication会自动去解析cookie中的认证数据

     异常二:AddDeveloperSigningCredential()这个是开发的签名凭据,只能在开发使用,部署时需要更换。。这里一定要加上,不然会报No signing credential is configured 的错误。

    异常三:登录时用户登录之后,无法跳转回原网页,还是停留在登录页。查看信息报错 user  is not Authenticated  。解决方案:使用https

     

  • 相关阅读:
    SQL查询,点击三维图层,查询属性信息
    title标签的使用
    idea快捷键大全
    intellij idea创建第一个动态web项目
    IDEA设置为黑色背景(今天开始使用idea,并记录点滴,记录坑)
    Eclipse导出Jar包(包含外部包)
    获取当前系统时间
    JS实现的ajax和同源策略
    缓存
    Restful Framework (四)
  • 原文地址:https://www.cnblogs.com/choii/p/13876789.html
Copyright © 2020-2023  润新知