一、创建一个空的api项目

添加identityserver4的nuget包

配置config文件

public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new IdentityResource[]
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
};
}
/// <summary>
/// API信息
/// </summary>
/// <returns></returns>
public static IEnumerable<ApiResource> GetApis()
{
return new[]
{
new ApiResource(IdentityServerConstants.LocalApi.ScopeName),
new ApiResource("manageApi", "Demo API with Swagger")
};
}
/// <summary>
/// 客服端信息
/// </summary>
/// <returns></returns>
public static IEnumerable<Client> GetClients()
{
return new[]
{
new Client
{
ClientId = "clientId",//客服端名称
ClientName = "Swagger UI for demo_api",//描述
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword ,//指定允许的授权类型(AuthorizationCode,Implicit,Hybrid,ResourceOwner,ClientCredentials的合法组合)。
AllowAccessTokensViaBrowser = true,//是否通过浏览器为此客户端传输访问令牌
AccessTokenLifetime = 3600*24,
AuthorizationCodeLifetime=3600*24,
ClientSecrets ={new Secret("secret".Sha256())},
//RedirectUris =
//{
// "http://localhost:59152/oauth2-redirect.html"
//},
AllowedCorsOrigins = new string[]{ "http://localhost:9012", "http://101.133.234.110:21004", "http://115.159.83.179:21004" },
AllowedScopes = { "manageApi", IdentityServerConstants.LocalApi.ScopeName }//指定客户端请求的api作用域。 如果为空,则客户端无法访问
}
};
}

在Startup.cs中注入IdentityServer服务并使用中间件

 //配置身份服务器与内存中的存储,密钥,客户端和资源
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(config.GetApis())//添加api资源
.AddInMemoryClients(config.GetClients())//添加客户端
.AddInMemoryIdentityResources(config.GetIdentityResources())//添加对OpenID Connect的支持
//使用自定义验证
.AddResourceOwnerValidator<CustomResourceOwnerPasswordValidator>()
.AddProfileService<ProfileService>();
//启用IdentityServer
app.UseIdentityServer();

接下来,我们去实现CustomResourceOwnerPasswordValidator这个类

创建一个CustomResourceOwnerPasswordValidator类,继承IResourceOwnerPasswordValidator

 public class CustomResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
public Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
{
throw new NotImplementedException();
}
}

接下来,我们就是些验证了

我们创建一个服务,去获取数据库里面的用户,验证是否有当前登录的用户

这里我们创建了一个userservice来验证我们的输入用户是否存在

  public class UserService : IUserService
{
public async Task<TestPhoneUser> ValidateCredentials(string nameorphone, string password)
{
var dto= TestUser.FirstOrDefault(c => c.Phone == nameorphone && password == c.PassWord);
if (dto != null)
return dto;
else
return null;
}
public class TestPhoneUser
{
/// <summary>
/// 唯一标识
/// </summary>
public int Id { get; set; }
/// <summary>
/// 手机号
/// </summary>
public string Phone { get; set; }
/// <summary>
/// 密码
/// </summary>
public string PassWord { get; set; }
}
public List<TestPhoneUser> TestUser = new List<TestPhoneUser>
{
new TestPhoneUser
{
Id=1,
Phone="12345678911",
PassWord="123qwe"
},new TestPhoneUser
{
Id=2,
Phone="123",
PassWord="123qwe"
}
}; }

现在,我们去完善CustomResourceOwnerPasswordValidator

public class CustomResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
private readonly IUserService _userService; public CustomResourceOwnerPasswordValidator(IUserService userService)
{
_userService = userService;
}
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
{
var dto = await _userService.ValidateCredentials(context.UserName, context.Password);
if (dto!=null)
{
context.Result = new GrantValidationResult(
dto.Id.ToString(),
"pwd",
DateTime.Now);
}
else
{
//验证失败
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "用户名密码错误");
}
}
}

再要配置profile

 public class ProfileService:IProfileService
{
public Task GetProfileDataAsync(ProfileDataRequestContext context)
{
context.IssuedClaims = context.Subject.Claims.ToList();
return Task.CompletedTask;
} public Task IsActiveAsync(IsActiveContext context)
{
context.IsActive = true; return Task.CompletedTask;
}
}

注入刚刚添加的服务

 services.AddScoped<IUserService, UserService>();
services.AddScoped<IProfileService, ProfileService>();

在Startup.cs中加入identityServer验证

 //用户校验
services.AddLocalApiAuthentication(); services.AddAuthorization(options =>
{
options.AddPolicy(IdentityServerConstants.LocalApi.PolicyName, policy =>
{
policy.AddAuthenticationSchemes(IdentityServerConstants.LocalApi.AuthenticationScheme);
policy.RequireAuthenticatedUser();
});
});
            app.UseAuthentication();

postman测试

反复验证了很多遍,都没有问题(因为我之前core2.x的时候就是这样写的)

最后去identityserver官网,找到了问题所在

现在的资源都换成了apiscope

然后,我把ApiResource都换成了ApiScope然后再运行

ok,完美!!!(这个坑,坑了我一下午)

最后再给api添加验证就行了

[Authorize(LocalApi.PolicyName)]

访问api

访问成功

参考文献:https://identityserver4.readthedocs.io/en/latest/quickstarts/1_client_credentials.html#defining-an-api-scope

IdentityServer4与API单项目整合(net core 3.X)的更多相关文章

  1. IdentityServer4实战 - 与API单项目整合

    一.前言 我们在实际使用 IdentityServer4 的时候,可能会在使用 IdentityServer4 项目添加一些API,比如 找回密码.用户注册.修改用户资料等,这些API与Identit ...

  2. ssm单项目整合

    目录 前言 创建maven项目 添加依赖 配置文件 总览 jdbc配置 mybatis配置 dao层配置 service层配置 事务配置 controller配置 web.xml 使用 前言 spri ...

  3. Swagger与SpringMVC项目整合

    Swagger与SpringMVC项目整合 来源:http://www.2cto.com/kf/201502/376959.html 为了方便的管理项目中API接口,在网上找了好多关于API接口管理的 ...

  4. 企业项目实战 .Net Core + Vue/Angular 分库分表日志系统 | 简单的分库分表设计

    前言 项目涉及到了一些设计模式,如果你看的不是很明白,没有关系坚持下来,写完之后去思考去品,你就会有一种突拨开云雾的感觉,所以请不要在半途感觉自己看不懂选择放弃,如果我哪里写的详细,或者需要修正请联系 ...

  5. 企业项目实战 .Net Core + Vue/Angular 分库分表日志系统二 | 简单的分库分表设计

    教程预览 01 | 前言 02 | 简单的分库分表设计 03 | 控制反转搭配简单业务 04 | 强化设计方案 05 | 完善业务自动创建数据库 06 | 最终篇-通过AOP自动连接数据库-完成日志业 ...

  6. SSM项目整合基本步骤

    SSM项目整合 1.基本概念 1.1.Spring Spring 是一个开源框架, Spring 是于 2003  年兴起的一个轻量级的 Java  开发框架,由 Rod Johnson  在其著作  ...

  7. 基于aws api gateway的asp.net core验证

    本文是介绍aws 作为api gateway,用asp.net core用web应用,.net core作为aws lambda function. api gateway和asp.net core的 ...

  8. Discuz3.2与Java 项目整合单点登陆

    JAVA WEB项目与Discuz 论坛整合的详细步骤完全版目前未有看到,最近遇到有人在问,想到这个整个不是一时半会也解释不清楚.便把整个整合过程以及后续碰到的问题解决方案写下,以供参考. 原理 Di ...

  9. SSM 框架 ---项目整合

    一.SSM框架理解 Spring(业务层) Spring就像是整个项目中装配bean的大工厂,在配置文件中可以指定使用特定的参数去调用实体类的构造方法来实例化对象. Spring的核心思想是IoC(控 ...

随机推荐

  1. Robot Framework(8)——脚本语法示例记录

    大神写了一个Robot Framework的脚本,好多语法之前没接触过,就有了这篇,记录下来一起学习,欢迎纠错 第二三四五列,一般是入参,红色的表示必填的入参.浅灰色表示选填的入参.深灰色表示无需填写 ...

  2. 点击按钮出现时间javascrip代码

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  3. ISO8601

    日期和时间的组合表示法 合并表示时,要在时间前面加一大写字母T,如要表示东八区时间2004年5月3日下午5点30分8秒,可以写成2004-05-03T17:30:08+08:00或20040503T1 ...

  4. computed&watch

    computed 定义:根据其他属性被计算出来的值 computed :{ [key: string]: Function | { get: Function, set: Function } } 是 ...

  5. 基于伪分布式Hadoop搭建Hive平台详细教程

    一.搭建环境的前提条件 环境:Linux系统 Hadoop-2.6.0 MySQL 5.6 apache-hive-2.3.7 这里的环境不一定需要和我一样,基本版本差不多都ok的,所需安装包和压缩包 ...

  6. 2020重新出发,MySql基础,MySql数据库备份与恢复

    @ 目录 MySQL数据库备份与恢复 数据库为什么需要备份 MySQL备份类型 MySQL热备份及恢复 逻辑备份 mysqldump SELECT INTO-OUTFILE mydumper 裸文件备 ...

  7. 基于模板特化的Lua自动绑定系统

    LuaBind http://www.rasterbar.com/products/luabind.html http://blog.sina.com.cn/s/blog_646817c00100gk ...

  8. AOP理论

    目录 AOP理论 什么是AOP 那Spring AOP,AspectJ又是啥呢? 为什么说AOP是OOP的补充和完善呢? 应用场景举例 AOP的优点 AOP的术语整理 AOP理论 什么是AOP AOP ...

  9. Codeforces1249E By Elevator or Stairs?

    题意 给定整数c和数组a,b,\(a_i\)表示通过爬楼梯的方法从第\(i\)层到\(i+1\)层需要的时间,\(b_i\)表示通过坐电梯的方法从第\(i\)层到\(i+1\)层需要的时间,坐电梯前需 ...

  10. C007:输入美元数量,用最少的20美元,10美元,5美元和1美元付款

    代码: #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { int amount; do{ printf(&quo ...