如果盗墓的事放到d城,又或东部沿海任何一个大城市边缘,那么相信警察很容易就可以控制局面。

“不愧是擅长空间之力的太虚古龙麻烦。”面对一星斗圣的太虚古龙刘皓也不敢小看,毕竟对方的肉体实在是强横被拍一掌的话不受伤那才叫奇怪。

克代尔菠萝啤有酒精吗

所以这一次的机会刘皓可不会轻易出手打破,不到最关键时刻他是不会出手帮助赤瞳,当然他不帮助赤瞳不代表他不出手对敌。
她冷冷地道:“也罢,我现在先放过你们,你们最好能跑多远便跑多远,若下次我再遇见你们,必让你们死无葬身之地。”

萧童是开车好手,沈静也会开车,就连王小民都有了驾照,三人轮换着开,一路上倒也顺利。

【ASP.NET Core分布式项目实战】(三)整理IdentityServer4 MVC授权、Consent功能实现


本博客根据http://video.jessetalk.cn/my/course/5视频整理(内容可能会有部分,推荐看源视频学习)

前言

由于之前的博客都是基于其他的博客进行开发,现在重新整理一下方便以后后期使用与学习

新建IdentityServer4服务端

服务端也就是提供服务,如QQ Weibo等。

新建项目解决方案AuthSample.

新建一个ASP.NET Core Web Application 项目MvcCookieAuthSample,选择模板Web 应用程序 不进行身份验证。

给网站设置默认地址     http://localhost:5000

第一步:添加Nuget包:IdentityServer4

添加IdentityServer4 引用:

Install-Package IdentityServer4

第二步:添加Config.cs配置类

然后添加配置类Config.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using IdentityServer4;
using IdentityServer4.Models;
using IdentityServer4.Test;

namespace MvcCookieAuthSample
{
    public class Config
    {
        //所有可以访问的Resource
        public static IEnumerable<ApiResource> GetApiResources()
        {
            return new List<ApiResource>()
            {
                new ApiResource("api1","API Application")
            };
        }

        //客户端
        public static IEnumerable<Client> GetClients()
        {
            return new List<Client>
            {
                new Client{
                    ClientId="mvc",
                    AllowedGrantTypes=GrantTypes.Implicit,//模式:隐式模式
                    ClientSecrets={//私钥
                        new Secret("secret".Sha256())
                    },
                    AllowedScopes={//运行访问的资源
                        IdentityServerConstants.StandardScopes.Profile,
                        IdentityServerConstants.StandardScopes.OpenId,
                    },
                    RedirectUris={"http://localhost:5001/signin-oidc"},//跳转登录到的客户端的地址
                    PostLogoutRedirectUris={"http://localhost:5001/signout-callback-oidc"},//跳转登出到的客户端的地址
                    RequireConsent=false//是否需要用户点击确认进行跳转
                }
            };
        }

        //测试用户
        public static List<TestUser> GetTestUsers()
        {
            return new List<TestUser>
            {
                new TestUser{
                    SubjectId="10000",
                    Username="wyt",
                    Password="password"
                }
            };
        }

        //定义系统中的资源
        public static IEnumerable<IdentityResource> GetIdentityResources()
        {
            return new List<IdentityResource>
            {
                //这里实际是claims的返回资源
                new IdentityResources.OpenId(),
                new IdentityResources.Profile(),
                new IdentityResources.Email()
            };
        }

    }
}
View Code

 

第三步:添加Startup配置

引用命名空间:

using IdentityServer4;

然后打开Startup.cs 加入如下:

services.AddIdentityServer()
                .AddDeveloperSigningCredential()//添加开发人员签名凭据
                .AddInMemoryApiResources(Config.GetApiResources())//添加内存apiresource
                .AddInMemoryClients(Config.GetClients())//添加内存client
                .AddInMemoryIdentityResources(Config.GetIdentityResources())//添加系统中的资源
                .AddTestUsers(Config.GetTestUsers());//添加测试用户
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ...
    app.UseIdentityServer();
    ...
}

注册登录实现

我们还需要新建一个ViewModels,在ViewModels中新建RegisterViewModel.cs和LoginViewModel.cs来接收表单提交的值以及来进行强类型视图

using System.ComponentModel.DataAnnotations;

namespace MvcCookieAuthSample.ViewModels
{
    public class RegisterViewModel
    {
        [Required]//必须的
        [DataType(DataType.EmailAddress)]//内容检查是否为邮箱
        public string Email { get; set; }

        [Required]//必须的
        [DataType(DataType.Password)]//内容检查是否为密码
        public string Password { get; set; }

        [Required]//必须的
        [DataType(DataType.Password)]//内容检查是否为密码
        public string ConfirmedPassword { get; set; }
    }
}
View Code
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace MvcCookieAuthSample.ViewModels
{
    public class LoginViewModel
    {

        [Required]
        public string UserName { get; set; }

        [Required]//必须的
        [DataType(DataType.Password)]//内容检查是否为密码
        public string Password { get; set; }
    }
}
View Code

在Controllers文件夹下新建AdminController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace MvcCookieAuthSample.Controllers
{
    public class AdminController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    }
}
View Code

在Views文件夹下新建Admin文件夹,并在Admin文件夹下新建Index.cshtml

@{
    ViewData["Title"] = "Admin";
}
<h2>@ViewData["Title"]</h2>

<p>Admin Page</p>
View Code

在Controllers文件夹下新建AccountController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using IdentityServer4.Test;
using Microsoft.AspNetCore.Identity;
using MvcCookieAuthSample.ViewModels;
using Microsoft.AspNetCore.Authentication;

namespace MvcCookieAuthSample.Controllers
{
    public class AccountController : Controller
    {
        private readonly TestUserStore _users;
        public AccountController(TestUserStore users)
        {
            _users = users;
        }

        //内部跳转
        private IActionResult RedirectToLocal(string returnUrl)
        {
            if (Url.IsLocalUrl(returnUrl))
            {//如果是本地
                return Redirect(returnUrl);
            }

            return RedirectToAction(nameof(HomeController.Index), "Home");
        }

        //添加验证错误
        private void AddError(IdentityResult result)
        {
            //遍历所有的验证错误
            foreach (var error in result.Errors)
            {
                //返回error到model
                ModelState.AddModelError(string.Empty, error.Description);
            }
        }

        public IActionResult Register(string returnUrl = null)
        {
            ViewData["returnUrl"] = returnUrl;
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> Register(RegisterViewModel registerViewModel, string returnUrl = null)
        {
            return View();
        }

        public IActionResult Login(string returnUrl = null)
        {
            ViewData["returnUrl"] = returnUrl;
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> Login(LoginViewModel loginViewModel, string returnUrl = null)
        {
            if (ModelState.IsValid)
            {
                ViewData["returnUrl"] = returnUrl;
                var user = _users.FindByUsername(loginViewModel.UserName);

                if (user==null)
                {
                    ModelState.AddModelError(nameof(loginViewModel.UserName), "UserName not exists");
                }
                else
                {
                    if (_users.ValidateCredentials(loginViewModel.UserName,loginViewModel.Password))
                    {
                        //是否记住
                        var prop = new AuthenticationProperties
                        {
                            IsPersistent = true,
                            ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromMinutes(30))
                        };

                        await Microsoft.AspNetCore.Http.AuthenticationManagerExtensions.SignInAsync(HttpContext, user.SubjectId, user.Username, prop);
                    }
                }

                return RedirectToLocal(returnUrl);
            }

            return View();
        }

        public async Task<IActionResult> Logout()
        {
            await HttpContext.SignOutAsync();
            return RedirectToAction("Index", "Home");
        }
    }
}
View Code

然后在Views文件夹下新增Account文件夹并新增Register.cshtml与Login.cshtml视图

@{
    ViewData["Title"] = "Register";
}

@using MvcCookieAuthSample.ViewModels;
@model RegisterViewModel;

<h2>@ViewData["Title"]</h2>
<h3>@ViewData["Message"]</h3>

<div class="row">
    <div class="col-md-4">
        @* 这里将asp-route-returnUrl="@ViewData["returnUrl"],就可以在进行register的post请求的时候接收到returnUrl *@
        <form method="post" asp-route-returnUrl="@ViewData["returnUrl"]">
            <h4>Create a new account.</h4>
            <hr />

           @*统一显示错误信息*@
            <div class="text-danger" asp-validation-summary="All"></div>

            <div class="form-group">
                <label asp-for="Email"></label>
                <input asp-for="Email" class="form-control" />
                <span asp-validation-for="Email" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Password"></label>
                <input asp-for="Password" class="form-control" />
                <span asp-validation-for="Password" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="ConfirmedPassword"></label>
                <input asp-for="ConfirmedPassword" class="form-control" />
                <span asp-validation-for="ConfirmedPassword" class="text-danger"></span>
            </div>
            <button type="submit" class="btn btn-default">Register</button>
        </form>
    </div>
</div>
View Code
@{
    ViewData["Title"] = "Login";
}

@using MvcCookieAuthSample.ViewModels;
@model LoginViewModel;

<div class="row">
    <div class="col-md-4">
        <section>
            <form method="post" asp-controller="Account" asp-action="Login"  asp-route-returnUrl="@ViewData["returnUrl"]">
                <h4>Use a local account to log in.</h4>
                <hr />

                 @*统一显示错误信息*@
                <div class="text-danger" asp-validation-summary="All"></div>

                <div class="form-group">
                    <label asp-for="UserName"></label>
                    <input asp-for="UserName" class="form-control" />
                    <span asp-validation-for="UserName" class="text-danger"></span>
                </div>

                <div class="form-group">
                    <label asp-for="Password"></label>
                    <input asp-for="Password" type="password" class="form-control" />
                    <span asp-validation-for="Password" class="text-danger"></span>
                </div>

                <div class="form-group">
                    <button type="submit" class="btn btn-default">Log in</button>
                </div>

            </form>
        </section>
    </div>
</div>

@section Scripts
    {
    @await Html.PartialAsync("_ValidationScriptsPartial")
}
View Code

我们接下来要修改_Layout.cshtml视图页面判断注册/登陆按钮是否应该隐藏

完整的_Layout.cshtml代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - MvcCookieAuthSample</title>

    <environment include="Development">
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
        <link rel="stylesheet" href="~/css/site.css" />
    </environment>
    <environment exclude="Development">
        <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
              asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
    </environment>
</head>
<body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a asp-area="" asp-controller="Home" asp-action="Index" class="navbar-brand">MvcCookieAuthSample</a>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
                    <li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
                    <li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
                </ul>

                @if (User.Identity.IsAuthenticated)
                {
                    <form asp-action="Logout" asp-controller="Account" method="post">
                        <ul class="nav navbar-nav navbar-right">
                            <li>
                                <a title="Welcome" asp-controller="Admin" asp-action="Index">@User.Identity.Name</a>
                            </li>
                            <li>
                                <button type="submit" class="btn btn-link navbar-btn navbar-link">Log out</button>
                            </li>
                        </ul>
                    </form>

                }
                else
                {
                    <ul class="nav navbar-nav navbar-right">
                        <li><a asp-area="" asp-controller="Account" asp-action="Register">Register</a></li>
                        <li><a asp-area="" asp-controller="Account" asp-action="Login">Log in</a></li>
                    </ul>
                }


            </div>
        </div>
    </nav>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; 2018 - MvcCookieAuthSample</p>
        </footer>
    </div>

    <environment include="Development">
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
        <script src="~/js/site.js" asp-append-version="true"></script>
    </environment>
    <environment exclude="Development">
        <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
                asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
                asp-fallback-test="window.jQuery"
                crossorigin="anonymous"
                integrity="sha384-K+ctZQ+LL8q6tP7I94W+qzQsfRV2a+AfHIi9k8z8l9ggpc8X+Ytst4yBo/hH+8Fk">
        </script>
        <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
                asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
                asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
                crossorigin="anonymous"
                integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa">
        </script>
        <script src="~/js/site.min.js" asp-append-version="true"></script>
    </environment>

    @RenderSection("Scripts", required: false)
</body>
</html>
View Code

最后给AdminController加上  [Authorize]  特性标签即可  

然后我们就可以运行网站,输入用户名和密码进行登录了

新建客户端 

新建一个MVC网站MvcClient 

dotnet new mvc --name MvcClient

给网站设置默认地址     http://localhost:5001

MVC的网站已经内置帮我们实现了Identity,所以我们不需要再额外添加Identity引用

添加认证

services.AddAuthentication(options =>
{
    options.DefaultScheme = "Cookies";//使用Cookies认证
    options.DefaultChallengeScheme = "oidc";//使用oidc
})
.AddCookie("Cookies")//配置Cookies认证
.AddOpenIdConnect("oidc",options=> {//配置oidc
    options.SignInScheme = "Cookies";
    options.Authority = "http://localhost:5000";
    options.RequireHttpsMetadata = false;

    options.ClientId = "mvc";
    options.ClientSecret = "secret";
    options.SaveTokens = true;
});

在管道中使用Authentication

app.UseAuthentication();

接下来我们在HomeController上打上  [Authorize]  标签,然后启动运行

我们这个时候访问首页http://localhost:5001会自动跳转到ocalhost:5000/account/login登录

登录之后会自动跳转回来

我们可以在Home/About页面将claim的信息显示出来

@{
    ViewData["Title"] = "About";
}
<h2>@ViewData["Title"]</h2>
<h3>@ViewData["Message"]</h3>

<dl>
    @foreach (var claim in User.Claims)
    {
        <dt>@claim.Type</dt>
        <dt>@claim.Value</dt>
    }
</dl>
View Code

 

 

 这边的内容是根据我们在IdentityServer服务中定义的返回资源决定的

Consent功能实现 

首先在ViewModels文件夹下创建两个视图模型

ScopeViewModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MvcCookieAuthSample.ViewModels
{
    //领域
    public class ScopeViewModel
    {
        public string Name { get; set; }
        public string DisplayName { get; set; }
        public string Description { get; set; }
        public bool Emphasize { get; set; }
        public bool Required { get; set; }
        public bool Checked { get; set; }
    }
}
View Code

ConsentViewModel.cs

相关新闻

好礼巨献,ThinkPad年“惠”来袭

2019-02-18 00:45:31

吉林乇皆柑电子有限公司

移动金融 创新生态

2019-02-18 00:32:14

衢州汾方信息科技有限公司

LOL 一句话了解国服新版本改动

2019-02-18 00:34:57

鞍山麓徊商贸有限公司

国网榆林公司:奏响优质服务“交响曲”

2019-02-18 00:20:35

昭通诓诨不经贸有限公司

热门推荐

  • 北方多地今起迎“天气变脸” 济南降温幅度或达20℃
  • 收购高通失败,博通将目标转向联发科
  • 外媒撰稿人:三星S9/S9+还保留耳机孔,是用户所需
  • [엠스플 in 오키나와] 이민우 “이번엔 KS 마운드 꼭 밟겠다.”
  • 宝马与长城达成合作,将国产宝马MINI电动车
  • Excel数据透视表“空白”?教你轻松解决
  • 西瓜视频将在京举办首届西瓜PLAY视频嘉年华
  • 主打空间实用性 铃木XBEE正式发布
  • 丢蛋蛋也是一项技术?史上最恶搞的《虎豹骑》兵种盘点
  • 四川茂县乡干部:整个乡村30多栋屋子只看获得一栋
  • 河北新闻网版权所有 本站点信息未经允许不得复制或镜像 法律顾问:电梯广告公司排名 微乐吉林长春棋牌官网
  • 西米来一把麻将河北省 copyright ? 2000 - 2016
  • 新闻热线:0311-67563366 广告热线:0311-67562966 新闻投诉:0311-67562994
  • 冀ICP备 09047539号-1 | 互联网新闻信息服务许可证编号:1312006002
  • 广播电视节目制作经营许可证(冀)字第101号|信息网络传播视听节目许可证0311618号
  • 麻将棋牌神助手 众乐乐棋牌作弊器 山水云南麻将下载ios 麻将机万能遥控器