资料

我们基于之前的MvcCookieAuthSample来做开发

MvcCookieAuthSample下载地址:https://files.cnblogs.com/files/wyt007/ASPNETCore%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8.rar

MvcCookieAuthSample教程地址:http://www.cnblogs.com/wyt007/p/8204731.html

正文

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

首先,我们将之前写的系统的Identity注释掉,在Startup.cs中

第一步:添加Nuget包:IdentityServer4

我们可以在vscode中使用ctrl+P键来打开命令面板。然后输入nuget按回车,输入identityserver4后按回车来选择版本进行安装

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

我们接下来添加一个Config.cs类,这个类是用来初始化IdentityServer的

using System.Collections;
using System.Collections.Generic;
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={//可以访问的Resource
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="",
Username="wyt",
Password="password"
}
};
} //定义系统中的资源
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Email()
};
} }
}

以上使用IdentityServer4测试数据类添加数据,直接存在内存中。IdentityServer4 是支持持久化。

第三步:添加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, ILoggerFactory loggerFactory)
{
...
//app.UseAuthentication();
app.UseIdentityServer();
...

接着安装UI,UI部分也可以自己编写,也就是登录 注销 允许和错误。

可以到 https://github.com/IdentityServer/IdentityServer4.Quickstart.UI/tree/release 下载,然后解压到项目目录下。

也可以使用命令提示符快速安装:

powershell iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/IdentityServer/IdentityServer4.Quickstart.UI/release/get.ps1'))

在项目目录下打开命令提示符,输入以上命令。

更多信息,可以查看官方readme:https://github.com/IdentityServer/IdentityServer4.Quickstart.UI/blob/release/README.md

大神博客:https://www.cnblogs.com/linezero/p/identityserver4openidconnect.html

修改LoginViewModel,将Email改为UserName,并修改强类型视图的引用部分Login.cshtml

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

修改AccountController,原来的_userManager和_signInManager不再使用

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authentication.Cookies;
using System.Security.Claims;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using Microsoft.AspNetCore.Identity;
using MvcCookieAuthSample.Models;
using System.Threading.Tasks;
using MvcCookieAuthSample.ViewModels;
using IdentityServer4.Test;
using System; namespace MvcCookieAuthSample.Controllers
{
public class AccountController : Controller
{
// private UserManager<ApplicationUser> _userManager;//创建用户的
// private SignInManager<ApplicationUser> _signInManager;//用来登录的 private readonly TestUserStore _users;
public AccountController(TestUserStore users)
{
_users=users;
} // //依赖注入
// public AccountController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager)
// {
// _userManager = userManager;
// _signInManager = signInManager;
// } //内部跳转
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)
{
// if (ModelState.IsValid)
// {
// ViewData["returnUrl"] = returnUrl; // var identityUser = new ApplicationUser
// {
// Email = registerViewModel.Email,
// UserName = registerViewModel.Email,
// NormalizedUserName = registerViewModel.Email
// };
// var identityResult = await _userManager.CreateAsync(identityUser, registerViewModel.Password);
// if (identityResult.Succeeded)
// {
// //注册完成登录生成cookies信息
// await _signInManager.SignInAsync(identityUser, new AuthenticationProperties { IsPersistent = true }); // return RedirectToLocal(returnUrl);
// }
// else//注册失败
// {
// //添加验证错误
// AddError(identityResult);
// }
// } 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 = await _userManager.FindByEmailAsync(loginViewModel.Email);
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))
}; //HttpContext.SignInAsync(user.SubjectId, user.Username, prop);
await Microsoft.AspNetCore.Http.AuthenticationManagerExtensions.SignInAsync(HttpContext, user.SubjectId, user.Username, prop);
}
}
//账号密码先不做验证,需要可以自己写
//await _signInManager.SignInAsync(user, new AuthenticationProperties { IsPersistent = true }); return RedirectToLocal(returnUrl);
} return View(); } //登出
public async Task<IActionResult> Logout()
{ await HttpContext.SignOutAsync();
return RedirectToAction("Index", "Home");
} }
}

接下来我们需要将原来的Program.cs中的数据库初始化的内容注释掉

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

新建客户端

新建一个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();

Login.cshtml 页面接收returnUrl进行跳转

<form method="post" asp-controller="Account" asp-action="Login">
<h4>Use a local account to log in.</h4>
<hr />
@*用于登录后进行跳转*@
<input type="hidden" name="returnUrl" value="@ViewData["returnUrl"]" /> <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-block btn-danger">Log in</button>
</div> </form>

接下来我们在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>

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

【ASP.NET Core分布式项目实战】(二)oauth2 + oidc 实现 server部分的更多相关文章

  1. ASP.NET Core分布式项目实战

    ASP.NET Core开发者成长路线图 asp.net core 官方文档 https://docs.microsoft.com/zh-cn/aspnet/core/getting-started/ ...

  2. 【笔记目录2】ASP.NET Core分布式项目实战

    当前标签: ASP.NET Core分布式项目实战 共2页: 上一页 1 2  11.ClientCredential模式总结 GASA 2019-03-11 12:59 阅读:26 评论:0 10. ...

  3. 【笔记目录1】ASP.NET Core分布式项目实战

    当前标签: ASP.NET Core分布式项目实战 共2页: 1 2 下一页  35.Docker安装Mysql挂载Host Volume GASA 2019-06-20 22:02 阅读:51 评论 ...

  4. ASP.NET Core分布式项目实战-目录

    前言 今年是2018年,发现已经有4年没有写博客了,在这4年的时光里,接触了很多的.NET技术,自己的技术也得到很大的进步.在这段时光里面很感谢张队长以及其他开发者一直对.NET Core开源社区做出 ...

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

    本博客根据http://video.jessetalk.cn/my/course/5视频整理(内容可能会有部分,推荐看源视频学习) 前言 由于之前的博客都是基于其他的博客进行开发,现在重新整理一下方便 ...

  6. 【ASP.NET Core分布式项目实战】(五)Docker制作dotnet core控制台程序镜像

    Docker制作dotnet core控制台程序镜像 基于dotnet SDK 新建控制台程序 mkdir /home/console cd /home/console dotnet new cons ...

  7. 【ASP.NET Core分布式项目实战】(一)IdentityServer4登录中心、oauth密码模式identity server4实现

    本博客根据http://video.jessetalk.cn/my/course/5视频整理 资料 OAuth2 流程:http://www.ruanyifeng.com/blog/2014/05/o ...

  8. 【ASP.NET Core分布式项目实战】(六)Gitlab安装

    Gitlab GitLab是由GitLabInc.开发,使用MIT许可证的基于网络的Git仓库管理工具,且具有wiki和issue跟踪功能.使用Git作为代码管理工具,并在此基础上搭建起来的web服务 ...

  9. 【ASP.NET Core分布式项目实战】(四)使用mysql/mysql-server安装mysql

    Docker安装Mysql 拉取镜像 docker pull mysql/mysql-server 运行mysql docker run -d -p : --name mysql01 mysql/my ...

随机推荐

  1. 海量日志采集系统flume架构与原理

    1.Flume概念 flume是分布式日志收集系统,将各个服务器的数据收集起来并发送到指定地方. Flume是Cloudera提供的一个高可用.高可靠.分布式的海量日志采集.聚合和传输的系统.Flum ...

  2. String、StringBuilder和StringBuffer类

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  3. 关于python的itertools模块

    这是一个强大的模块 先来看一下它都有什么工具 无穷循环器 迭代器         参数         结果                                               ...

  4. 【java】对象变成垃圾被垃圾回收器gc收回前执行的操作:Object类的protected void finalize() throws Throwable

    package 对象被回收前执行的操作; class A{ @Override protected void finalize() throws Throwable { System.out.prin ...

  5. 垃圾回收机制GC知识再总结兼谈如何用好GC(转)

    作者:Jeff Wong 出处:http://jeffwongishandsome.cnblogs.com/ 本文版权归作者和博客园共有,欢迎围观转载.转载时请您务必在文章明显位置给出原文链接,谢谢您 ...

  6. 在IntelliJ IDEA里创建简单的基于Maven的SpringMVC项目

    后来发现了一种更加方便的创建方式,即第一步不选择Create from archetype,创建完毕后打开Project Structure-Modules,然后添加Web,但是注意添加的Web里面的 ...

  7. [置顶] webapi token、参数签名是如何生成的

    一个问题 在这里我想问大家一句,如果你向一个刚刚接触.net web后端程序开发的同学(别人刚刚也就学了webform的request,response,会提交表单的这种刚接触不久的同学),你怎么去解 ...

  8. ArcGIS API for JavaScript 4.2学习笔记[13] Layer的弹窗(PopupTemplate)

    上一篇文章中讲到Popup是一个弹窗,是View对象的默认内置弹窗,并且在View对象构造时就顺便构造了. 那么这个PopupTemplate是什么呢? 后半截单词Template是"模板& ...

  9. js怎么防止变量冲突

    [1]工程师甲编写功能A ? 1 2 3 var a = 1; var b = 2; alert(a+b);//3 [2]工程师乙添加新功能B ? 1 2 3 var a = 2; var b = 1 ...

  10. 线上平滑升级nginx1.12

    .下载相关包,需要和之前用到的依赖包保持一致 wget http://nginx.org/download/nginx-1.12.2.tar.gz wget https://bitbucket.org ...