.Net Core 3.0 IdentityServer4 快速入门

              —— resource owner password credentials(密码模式)

一、前言

  OAuth2.0默认有四种授权模式(GrantType):

    1)授权码模式

    2)简化模式

    3)密码模式(resource owner password credentials)

    4)客户端模式(client_credentials)

  上一小节接受了 客户端模式 ,本小节将介绍 密码模式,OAuth2.0资源所有者密码授权功能允许客户端将用户名和密码发送到授权服务器,并获得该用户的访问令牌

  认证步骤:

    

    1)用户将用户名和密码提供给客户端

    2)客户端再将用户名和密码发送给授权服务器(Id4)请求令牌

    3)授权服务器(Id4)验证用户的有效性,返回给客户端令牌

    4)Api资源收到第一个(首次)请求之后,会到授权服务器(Id4)获取公钥,然后用公钥验证Token是否合法,如果合法将进行后面的有效性验证,后面的请求都会用首次请求的公钥来验证(jwt去中心化验证的思想)

    Resource Owner 其实就是User,密码模式相较于客户端模式,多了一个参与者,就是User,通过User的用户名和密码向Identity Server 申请访问令牌,这种模式下要求客户端不得存储密码,但我们并不能确保客户端是否存储了密码,所以该模式仅仅适用于受信任的客户端。因此该模式不推荐使用

二、创建授权服务器

  

  1)安装Id4  

 

  2)创建一个Config类模拟配置要保护的资源和可以访问的api客户端服务器

 using IdentityServer4;
using IdentityServer4.Models;
using IdentityServer4.Test;
using System.Collections.Generic; namespace IdentityServer02
{
public static class Config
{
/// <summary>
/// 需要保护的api资源
/// </summary>
public static IEnumerable<ApiResource> Apis =>
new List<ApiResource>
{
new ApiResource("api1","My Api")
};
public static IEnumerable<Client> Clients =>
new List<Client>
{
//客户端
new Client
{
ClientId="client",
ClientSecrets={ new Secret("aju".Sha256())},
AllowedGrantTypes=GrantTypes.ResourceOwnerPassword,
//如果要获取refresh_tokens ,必须在scopes中加上OfflineAccess
AllowedScopes={ "api1", IdentityServerConstants.StandardScopes.OfflineAccess},
AllowOfflineAccess=true
}
}; public static List<TestUser> Users = new List<TestUser>
{
new TestUser
{
SubjectId="",
Password="Aju_001",
Username="Aju_001"
},
new TestUser
{
SubjectId="",
Password="Aju_002",
Username="Aju_002"
}
};
}
}

  与客户端模式不一致的地方就在于(AllowedGrantTypes=GrantTypes.ResourceOwnerPassword)此处设置为资源所有者(密码模式)

  3)配置StartUp

 using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; namespace IdentityServer02
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
var builder = services.AddIdentityServer()
.AddInMemoryApiResources(Config.Apis)
.AddInMemoryClients(Config.Clients)
.AddTestUsers(Config.Users); builder.AddDeveloperSigningCredential();
} // 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();
}
// app.UseRouting();
app.UseIdentityServer();
}
}
}

  5)验证配置是否成功

  在浏览器中输入(http://localhost:5000/.well-known/openid-configuration)看到如下发现文档算是成功的

三、创建Api资源

  1)步骤如创建授权服务的1)

  2)安装包

  3)创建一个受保护的ApiController

 using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Linq; namespace Api02.Controllers
{
[Route("Api")]
[Authorize]
public class ApiController : ControllerBase
{
public IActionResult Get()
{
return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
}
}
}

  4)配置StartUp

 using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; namespace Api02
{
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.AddControllers();
services.AddAuthentication("Bearer").AddJwtBearer("Bearer", options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.Audience = "api1";
});
} // 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();
} app.UseRouting(); app.UseAuthentication();//认证
app.UseAuthorization();//授权 app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

四、创建客户端(控制台 模拟客户端)

 using IdentityModel.Client;
using Newtonsoft.Json.Linq;
using System;
using System.Net.Http;
using System.Threading.Tasks; namespace Client02
{
class Program
{
static async Task Main(string[] args)
{
// Console.WriteLine("Hello World!");
var client = new HttpClient();
var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");
if (disco.IsError)
{
Console.WriteLine(disco.Error);
return;
}
var tokenResponse = await client.RequestPasswordTokenAsync(
new PasswordTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "client",
ClientSecret = "aju",
Scope = "api1 offline_access",
UserName = "Aju",
Password = "Aju_password"
});
if (tokenResponse.IsError)
{
Console.WriteLine(tokenResponse.Error);
return;
}
Console.WriteLine(tokenResponse.Json);
Console.WriteLine("\n\n");
//call api
var apiClient = new HttpClient();
apiClient.SetBearerToken(tokenResponse.AccessToken);
var response = await apiClient.GetAsync("http://localhost:5001/api");
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response.StatusCode);
}
else
{
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(JArray.Parse(content));
}
Console.ReadLine();
}
}
}

五、验证

  1)直接获取Api资源

  出现了401未授权提示,这就说明我们的Api需要授权

  2)运行客户端访问Api资源

六、自定义用户验证

  在创建授权服务器的时候我们在Config中默认模拟(写死)两个用户,这显得有点不太人性化,那我们就来自定义验证用户信息

  1)创建 自定义 验证 类 ResourceOwnerValidator

 using IdentityModel;
using IdentityServer4.Models;
using IdentityServer4.Validation;
using System.Threading.Tasks; namespace IdentityServer02
{
public class ResourceOwnerValidator : IResourceOwnerPasswordValidator
{
public Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
{
if (context.UserName == "Aju" && context.Password == "Aju_password")
{
context.Result = new GrantValidationResult(
subject: context.UserName,
authenticationMethod: OidcConstants.AuthenticationMethods.Password);
}
else
{
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "无效的秘钥");
}
return Task.FromResult("");
}
}
}

  2)在授权服务器StartUp配置类中,修改如下:

  

   3)在客户端中将 用户名 和 密码 修改成 我们在自定义 用户 验证类 中写的用户名和密码,进行测试

七、通过refresh_token 获取 Token

  1)refresh_token

    获取请求授权后会返回 access_token、expire_in、refresh_token 等内容,每当access_token 失效后用户需要重新授权,但是有了refresh_token后,客户端(Client)检测到Token失效后可以直接通过refresh_token向授权服务器申请新的token

八、参考文献

  http://docs.identityserver.io/en/latest/index.html

  如果对您有帮助,请点个推荐(让更多需要的人看到哦)

.Net Core 3.0 IdentityServer4 快速入门02的更多相关文章

  1. .Net Core 3.0 IdentityServer4 快速入门

    .Net Core 3.0 IdentityServer4 快速入门 一.简介 IdentityServer4是用于ASP.NET Core的OpenID Connect和OAuth 2.0框架. 将 ...

  2. Spring Boot 2.0 的快速入门(图文教程)

    摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! Spring Boot 2.0 的快速入门(图文教程) 大家都 ...

  3. .Net Core 2.0 EntityFrameworkCore CodeFirst入门教程

    最近难得有时间闲下来,研究了一下.net core 2.0,总的来说,目前除了一些第三方的库不支持外,基本上可以满足我们的项目需求了! 我们就以一个网站开发为例,搭建一个简单的三层架构,先熟悉一下.n ...

  4. 从0开始快速入门学Java----基本篇

    由于是0基础入门java,所以花了比较多的时间学习了基本语法知识,阶段性梳理下知识: 1. Java的介绍+JDK安装及环境变量配置+第一个程序HelloWorld的编写 这部分开始遇到的问题比较多, ...

  5. NSIS 2.0界面快速入门

    NSIS 2.0 版本支持定制的用户界面.所谓的 Modern UI(下称 MUI) 就是一种模仿最新的 Windows 界面风格的界面系统.MUI 改变了 NSIS 脚本的编写习惯,它使用 NSIS ...

  6. ETCD快速入门-02 ETCD安装

    2.ETCD安装     etcd 安装可以通过源码构建也可以使用官方构建的二进制文件进行安装.我们以二进制文件为例,系统为CentOS 7.9,操作步骤如下所示: 2.1 Linux ETCD_VE ...

  7. React Router 4.0中文快速入门

    import React from 'react' import { BrowserRouter as Router, Route, Link } from 'react-router-dom' co ...

  8. docker快速入门02——在docker下开启mysql5.6 binlog日志

    1.检查容器状态 [root@localhost ~]# docker ps 执行这个命令可以看到所有正在运行当中的容器,如果加上-a参数,就可以看到所有的容器包括停止的. 我们可以看到容器正在运行当 ...

  9. 微信小程序_快速入门02

    01我们学习了环境的准备和简单的demo,现在是时候来学习简单的页面编写了,首先我们来学习一些常用的基础标签: 一.view盒子,就是类似于div的盒子,可以用来存其他元素的容器. 二.text 文本 ...

随机推荐

  1. 【教程】Bluestacks0.7.9.860以上版3分钟教你摇一摇

    Bluestacks 0.7.9.860 版或以上 , 打开文件夹Win 7 用户 : C:\ProgramData\Bluestacks\UserData\InputMapperWin XP 用户 ...

  2. (转)阿里云CentOS 7下配置及使用mysql

    一.安装 1 正确的安装方法: 众所周知,Linux系统自带的repo是不会自动更新每个软件的最新版本(基本都是比较靠后的稳定版),所以无法通过yum方式安装MySQL的高级版本.所以我们需要先安装带 ...

  3. 错误:java.lang.NoClassDefFoundError: org/jaxen/JaxenException

    tomcat运行时候报错: java.lang.NoClassDefFoundError: org/jaxen/JaxenException at org.dom4j.DocumentFactory. ...

  4. Flume系列一之架构介绍和安装

    Flume架构介绍和安装 写在前面 在学习一门新的技术之前,我们得知道了解这个东西有什么用?我们可以使用它来做些什么呢?简单来说,flume是大数据日志分析中不能缺少的一个组件,既可以使用在流处理中, ...

  5. 2019-2020-1 20199303 《Linux内核原理分析》 第一周作业

    2019-2020-1 20199303 <Linux内核原理分析> 第一周作业 1. 环境准备 在众多的Linux发行版中,Ubuntu,小红帽还有类Unix系统的BSD系统,我选择了目 ...

  6. 在Debian上用FVWM做自己的桌面

    用FVWM做自己的桌面 Table of Contents 1. 前言 2. 学习步骤 3. 准备 3.1. 软件包 3.2. 字体 3.3. 图片 3.4. 参考资料 4. 环境 5. 布局 6. ...

  7. Spring 事务注解@Transactional

    事务管理一般有编程式和声明式两种,编程式是直接在代码中进行编写事物处理过程,而声名式则是通过注解方式或者是在xml文件中进行配置,相对编程式很方便. 而注解方式通过@Transactional 是常见 ...

  8. poi实现excel的导入导出功能

    Java使用poi实现excel的导入导出功能: 工具类ExcelUtil,用于解析和初始化excel的数据:代码如下 package com.raycloud.kmmp.item.service.u ...

  9. FastDfs之TrackerServer的详细配置介绍

    # is this config file disabled # false for enabled # true for disabled disabled=false #当前配置是否不可用fals ...

  10. Spring Cloud 全链路追踪实现

    简介 在微服务架构下存在多个服务之间的相互调用,当某个请求变慢或不可用时,我们如何快速定位服务故障点呢?链路追踪的实现就是为了解决这一问题,本文采用Sleuth+Zipkin+RabbitMQ+ES+ ...