一、创建一个空的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. QPS过万,redis大量连接超时怎么解决?

    7月2号10点后,刚好某个负责的服务发生大量的redis连接超时的异常(redis.clients.jedis.exceptions.JedisConnectionException),由于本身的数据 ...

  2. 华为云配置Objected-based Storage System

    本实验要求基于开源的对象文件系统(例如Ceph),搭建视频点播(VoD)网站.可参考使用Ceph, wordpress, php 以及nginx 实现相关功能,主要包含以下方面: 配置Ceph; 配置 ...

  3. kali安装open-vm-tools实现虚拟机交互

    普通的VMware tools 弱爆了 安装具有复制粘贴功能的open-vm-tools.servic: 切记:如果之前已经安装了VMware tools,一定要删除:vmware-uninstall ...

  4. Vue的数据响应式

    getter和setter怎么用 示例代码 getter ,关键词为 get ,用于获取一个值.定义时为函数,但是使用时不用加括号. setter 用于对数据的改写 Object.defineProp ...

  5. 微信支付宝个人免签约即时到帐接口开发附demo

    支付界面: 扫码支付界面: 付成功后可以跳转到你程序指定的地址! demo: http://likeyunba.com/WeChat-Pay/

  6. DAO层,Service层,Controller层、View层、entity层

    1.DAO(mapper)层:DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,DAO层的设计首先是设计DAO的接口,然后在Spring的配置文件中定义此接口的实现类,然后就 ...

  7. Hive SQL 优化面试题整理

    Hive优化目标 在有限的资源下,执行效率更高 常见问题: 数据倾斜 map数设置 reduce数设置 其他 Hive执行 HQL --> Job --> Map/Reduce 执行计划 ...

  8. 消息型中间件之RabbitMQ基础使用

    1.概念 RabbitMQ是AMQP(高级消息队列协议)协议的实现主要功能用于分布式应用当中的各组件间解耦.在传统C/S架构中,如果客户端发送一个请求消息,服务端必须得在线,有了中间件,客户端不是非得 ...

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

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

  10. unimrcp plugin 分析

    摘要: unimrcp 访问媒体资源是通过插件实现,社区的代码给出了demo plugin,但是距离一个生产插件还是有一段的距离.这边文章介绍插件的整个逻辑过程,以及如何实现我们自己的插件.