IdentityServer4 保护.net framework webapi
一、IS4服务器配置
1、新建一个Asp.net Core MVC程序,模板选择 Empty

2、Nuget添加 IdentityServer4,我这里添加的是2.5.3
3、添加Config文件,配置clients和scopes等信息,需要持久化配置的可以看 https://www.cnblogs.com/fengchao1000/p/10184921.html
public class Config
{
// scopes define the resources in your system
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile()
};
} public static IEnumerable<ApiResource> GetApis()
{
return new List<ApiResource>
{
new ApiResource("FrameworkAPI",new List<string>(){JwtClaimTypes.Subject})
};
} public static IEnumerable<Client> GetClients()
{
return new List<Client>
{ //Implicit模式Client配置,适用于SPA
new Client
{
ClientId = "Test",
ClientName = "Test",
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
AccessTokenLifetime = *,
AccessTokenType = AccessTokenType.Jwt,
RedirectUris =
{
"https://localhost:5003/signin-callback.html",
"https://localhost:5003/silent-callback.html"
},
PostLogoutRedirectUris = { "https://localhost:5003" },
AllowedCorsOrigins = { "https://localhost:5003" },
RequireConsent = false,
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"FrameworkAPI"//对应webapi里面的scope配置
}
},
//ResourceOwnerPassword模式Client配置,适用于App、winform
new Client
{
ClientId = "App",
ClientName = "App",
ClientSecrets = { new Secret("".Sha256()) },
AccessTokenLifetime = *,//单位s
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
SlidingRefreshTokenLifetime = ,
AllowOfflineAccess = true,
AllowedScopes = new List<string>
{
"FrameworkAPI",//对应webapi里面的scope配置
StandardScopes.OfflineAccess,
StandardScopes.OpenId,
StandardScopes.Profile
}
} };
}
}
4、添加ProfileService文件,用于自定义登录返回信息
/// <summary>
/// 自定义用户登录返回的信息claims
/// </summary>
public class ProfileService : IProfileService
{
private readonly ILogger logger; public ProfileService(ILogger<ProfileService> logger)
{
this.logger = logger;
} public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
try
{
var claims = context.Subject.Claims.ToList(); context.IssuedClaims = claims.ToList();
}
catch (Exception ex)
{
logger.LogError(ex.ToString());
}
} public async Task IsActiveAsync(IsActiveContext context)
{
context.IsActive = true;
}
}
5、添加ResourceOwnerPasswordValidator文件,在ResourceOwnerPassword模式下用于自定义登录验证
/// <summary>
///ResourceOwnerPassword模式下用于自定义登录验证
/// </summary>
public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
{
private readonly IConfiguration config; public ResourceOwnerPasswordValidator(IConfiguration config)
{
this.config = config;
} public Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
{
//根据context.UserName和context.Password与数据库的数据做校验,判断是否合法
if (context.UserName == "test" && context.Password == "test")
{
context.Result = new GrantValidationResult(
subject: context.UserName,
authenticationMethod: OidcConstants.AuthenticationMethods.Password);
}
else
{
//验证失败
context.Result = new GrantValidationResult(
TokenRequestErrors.InvalidGrant,
"invalid custom credential"
);
}
return Task.FromResult();
}
}
6、在 Startup 配置IdentityServer
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)
{
services.AddIdentityServer()
//配置证书
.AddDeveloperSigningCredential()
//配置API资源
.AddInMemoryApiResources(Config.GetApis())
//配置身份资源
.AddInMemoryIdentityResources(Config.GetIdentityResources())
//预置Client
.AddInMemoryClients(Config.GetClients())
.AddProfileService<ProfileService>()
.AddResourceOwnerValidator<ResourceOwnerPasswordValidator>(); services.AddAuthentication()
.AddCookie(options =>
{
options.ExpireTimeSpan = System.TimeSpan.FromMinutes();
options.SlidingExpiration = true;
});
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseIdentityServer();//IdentityServer4中间件 app.Run(async (context) =>
{
await context.Response.WriteAsync("IdentityServer4");
});
}
}
到这里我们IdentityServer4服务端已经搭建好了,我们用postman测试下,这里调用的是ResourceOwnerPassword模式

二、.net framework webapi 配置
1、新建一个 .net framework webapi 程序
\
2、由于webapi是.net Framework版本的,所以我们需要引用 IdentityServer3.AccessTokenValidation 作为api端token的验证组件。
Nuget添加:
IdentityServer3.AccessTokenValidation
IdentityModel
Microsoft.Owin.Host.SystemWeb
3、添加一个 Owin Startup.cs ,最好是用现有的startup类,而不要自己去新建一个类,然后修改名称。

4、在Startup中配置 IdentityServer AccessToken 验证参数
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "http://localhost:62527/",
RequiredScopes = new[] { "FrameworkAPI" },//对应Client中配置的AllowedScopes和ApiResource DelayLoadMetadata = true
}); }
}
5、在 WebAPIConfig 中加入 config.Filters.Add(new AuthorizeAttribute()) 来启用授权验证
config.Filters.Add(new AuthorizeAttribute());
6、添加TestController
public class TestController : ApiController
{
public IHttpActionResult Get()
{
var user = User as ClaimsPrincipal; var claims = from c in user.Claims
select new
{
type = c.Type,
value = c.Value
}; return Json(claims);
}
}
最后项目结构如下:

三、测试
我们的服务端和webapi都已经配置好了,我们用postman测试下
1、直接访问api地址 http://localhost:44387/test ,不加入token ,得到如下结果,返回401
2、加入token ,验证通过,返回200

IdentityServer4 保护.net framework webapi的更多相关文章
- 大话IdentityServer4之使用 IdentityServer4 保护 ASP.NET Core 应用
这几天一直在研究IdentityServer4在asp.net core3.0中的应用,下面说说我的理解: 我们每一个.net core 项目大家可以理解为我新建了一个动物园或者植物园等,注册用户想要 ...
- C# Autofac集成之Framework WebAPI
Web API 2集成需要Autofac.WebApi2 NuGet包. Web API集成需要Autofac.WebApi NuGet包. Web API集成为控制器,模型绑定器和操作过滤器提供了依 ...
- 创建.net framework webapi出现“Web 服务器被配置为不列出此目录的内容。”错误
接了一个新任务,要求写一个web api.于是我创建了一个.net framework的web api,结果在运行的时候,出现了以下页面: 解决方法: 在web.config文件中添加<dire ...
- asp.net core使用identity+jwt保护你的webapi(一)——identity基础配置
前言 用户模块几乎是每个系统必备的基础功能,如果每次开发一个新项目时都要做个用户模块,确实非常无聊.好在asp.net core给我们提供了Identity,使用起来也是比较方便,如果对用户这块需求不 ...
- asp.net core使用identity+jwt保护你的webapi(二)——获取jwt token
前言 上一篇已经介绍了identity在web api中的基本配置,本篇来完成用户的注册,登录,获取jwt token. 开始 开始之前先配置一下jwt相关服务. 配置JWT 首先NuGet安装包: ...
- asp.net core使用identity+jwt保护你的webapi(三)——refresh token
前言 上一篇已经介绍了identity的注册,登录,获取jwt token,本篇来完成refresh token. 开始 开始之前先说明一下为什么需要refresh token. 虽然jwt toke ...
- AspNetCore网关集成Swagger访问使用IdentityServer保护的webapi项目
创建webapi项目 创建四个webapi项目,两个处理业务,一个网关,一个验证中心.四个项目对应的端口如下, ApiGateway:1999 IdentityServer:16690 Service ...
- Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(一)
好吧,这个题目我也想了很久,不知道如何用最简单的几个字来概括这篇文章,原本打算取名<Angular单页面应用基于Ocelot API网关与IdentityServer4+ASP.NET Iden ...
- IdentityServer4系列 | 快速搭建简易项目
一 .前言 从上一篇关于 常见术语说明中,主要是对IdentityServer4的说明,以及其中涉及常见的术语的表述说明,包括对身份认证服务器.用户.客户端.资源以及各个令牌等进行对比区别说明. 而在 ...
随机推荐
- 常用html转义符,JavaScript转义符
HTML字符实体(Character Entities),转义字符串(Escape Sequence) 为什么要用转义字符串? HTML中<,>,&等有特殊含义(<,> ...
- 完美解决Python与anaconda之间的冲突问题
anaconda指的是一个开源的Python发行版本,其包含了conda.Python等180多个科学包及其依赖项.因为包含了大量的科学包,Anaconda 的下载文件比较大(约 515 MB),如果 ...
- python:__name__的使用
1.python中__name__是什么意思? 很多python的初学者可能都会遇到一个问题:__name__是什么意思? 在刚开始学习python的时候,我们总会看到这样一句代码: if __nam ...
- vue H5页面手机端 利用canvas 签名
签名首先用一个canvas标签,上面加三个代码,分别是点击,移动,离开.这里点击是开始画笔的地方,如果不加@touchstart 笔头会发生偏移,可以试试. @toucheend也是如此.尾巴也会出现 ...
- WPF项目设计规则
关于WPF应用程序的设计: 项目构成,自上而下: 1. 前端的WPF应用程序项目. 2. 业务逻辑的类库项目. 3. 映射到数据库各个表的Model型类库,(数据库操作接口定义). 4. 其他工具型类 ...
- Pandas IO 操作
数据分析过程中经常需要进行读写操作,Pandas实现了很多 IO 操作的API 格式类型 数据描述 Reader Writer text CSV read_csv to_csv text JSON r ...
- 【java基础】程序员你真的理解反射机制吗?
目录 前言 1.反射的概述 2.正式使用反射之前很有必要了解的Class类 3.反射的使用 前言 很多讲解反射的博客文章并没有详细讲解Class类,~当然包括之前的我也一样~,这样的文章只会让反射徒有 ...
- 测试面试题集-测试用例设计:登录、购物车、QQ收藏表情、转账、充值、提现
以下内容首发于微信公众号[ITester软件测试小栈]: 测试面试题集-2.测试用例设计 大家好 我是coco小锦鲤 上周五给大家分享了测试基础理论题 这个周五给大家分享测试用例设计题 测试用例的考察 ...
- N42期-qq-林友埙-第一周作业
1.按系列罗列Linux的发行版,并描述不同发行版之间的联系与区别. 基于Dpkg (Debian系) 商业发行版 o Ubuntu,一个非常流行的桌面发行版. 社区发行版 o Debian,一个强烈 ...
- python中函数名后面带()和不带()的区别。
今天天气不冷,微热.9.18警钟长鸣,国人当自强不息. python中有时候会遇到一个函数名称后面没有带()被调用,这是为什么呢?看下面这个例子. def target(): #定义一个函数 prin ...