Abp vNext Token
Abp vNext Token
Abp vNext 版本:5.3
Abp vNext 使用的是IdentityServer4
目录
Abp vNext 基本使用
Abp vNext 增删改查
Abp vNext Token
Abp vNext单点登录
Abp vNext自定义OpenIdDict登录
创建项目
abp new abpdemo --template app --ui none --separate-identity-server
IdentityServer4提供了八个API
/.well-known/openid-configuration/connect/authorize/connect/token/connect/userinfo/connect/deviceauthorization/connect/introspect/connect/revocation/connect/endsession
具体使用方式看官方文档的ENDPOINTS部分,我就记录一些常用的
http://docs.identityserver.io/en/latest/
https://identityserver4.readthedocs.io/en/latest/
获取 token
/api/account/login只是验证登录,并不返回token
Abp中获取token的接口是/connect/token
参数是来自Body的x-www-form-urlencoded类型,不需要access_token
必要参数
{
grant_type : "password",
username : "admin",
password : "1q2w3E*",
client_id : "dbpdemo_App"
}
grant_type根据数据库中的IdentityServerClientGrantTypes表的GrantType字段client_id根据数据库中的IdentityServerClients表的ClientId字段

注意
首先就是IdentityServer的ip端口,如果创建项目时使用了--separate-identity-server参数,那么WebAPI和IdentityServer的端口就不一样
HttpApi.Host的appsettings.json中的AuthServer.Authority必须和IdentityServer的appsettings.json中的App.SelfUrl一模一样,否则在验证Issuer的时候会报异常,状态码401
还有可能会报SSL证书异常,状态码500,这个就需要配置SSL证书了
System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'System.String'.
---> System.IO.IOException: IDX20804: Unable to retrieve document from: 'System.String'.
---> System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure: RemoteCertificateNameMismatch
还有个问题,即使前端的请求数据正确,也可能会出现invalid_client这样的返回值,需要使用qs.stringify()序列化数据再请求,我也不懂为什么
还有就是ip的问题,localhost和127.0.0.1是不一样的,可能引起401
获取用户信息
有两种方式,都是将token放到Authorization
-
/connect/userInfo
![]()
-
ICurrentUser
[ApiController]
[Route("/api/v1/[controller]")]
public class UserController : AbpControllerBase
{
private readonly ICurrentUser _currentUser;
public UserController(ICurrentUser currentUser)
{
this._currentUser = currentUser;
}
[HttpGet("GetCurrentUser")]
[Authorize]
public async Task<ActionResult> GetCurrentUser()
{
return Ok(this._currentUser);
}
}

撤销令牌
IdentityServer4提供了撤销access_token和refresh_token的API,/connect/revocation
这个API接收两个参数token和token_type_hint,就是令牌和令牌类型
可以在后端调用这个API去撤销令牌,前端也可以
调用比较麻烦
client_id:IdentityServerClients表的ClientId字段client_secret:IdentityServerClientSecrets表的Value字段,要对应ClientId
两种调用方式
不加验证,这样需要client_id和client_secret参数

加验证,把client_id和client_secret分别加入Username和Password,Body就不需要client_id和client_secret了

其实这里并不能使access_token过期,只能使refresh_token过期,我试过了,因为jwt生成的token信息是固定的,单纯校验token信息是不够的,所以还是redis好使
双token策略
- 在后端设置一个校验token的
IAuthorizationFilter过滤器,检查token的有效期,到了差不多的时间就在response中设置一个标识,由前端校验这个 - 在前端设置一个
response拦截器,校验响应中是否具有标识,有标识则在请求中带上refresh_token,然后刷新本地access_token和refresh_token
refresh_token只有前端第一次接收和第一次使用时才会在网络中传输,安全性比较高
refresh_token的使用方式还是/connect/token,但是参数不太一样,也不需要access_token
{
grant_type : "refresh_token",
refresh_token : "refresh_token",
client_id : "dbpdemo_App"
}

再次使用refresh_token发送请求,原先的refresh_token已经失效,access_token则需要等到有效时间结束,毕竟只是校验token规则
未使用refresh_token就重新登录去获取access_token和refresh_token,那么原先的refresh_token仍然有效

如果需要access_token和refresh_token都失效,即单点登录,可以将access_token放到redis,在WebApi中写一个中间件或者过滤器,在校验access_token之前先读取redis,刷新时将旧的access_token删除,这样做的缺点就是一个用户只能使用一个token,不适合多个客户端使用
刷新token时让旧token过期,如果前端一次发送多个异步请求,那么刷新token后其它请求的处理就比较头疼了,用redis解决还蛮简单的,比如给旧token设置30秒的有效期,写一个中间件/过滤器,在验证token过期时读取redis
XSRF-TOKEN
前端除GET以外请求可能会报这个异常
The required antiforgery header value "RequestVerificationToken" is not present.
就是防XSRF攻击用的,Abp vNext默认开启这个,在Swagger或者前端的Cookie里是可以看到有一个XSRF-TOKEN,除了GET请求都需要这个token,记得加到请求的header里,对应的属性是RequestVerificationToken,Postman不需要这个也能请求成功,小坑
也可以选择关闭这个验证,在HttpApi.Host项目中配置AntiForgery
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpAntiForgeryOptions>(options =>
{
//关闭POST的XSRF-TOKEN验证
options.AutoValidateIgnoredHttpMethods.Add("POST");
});
}
根据abp的官方文档,这个验证一般是对Razor用的,WebApi的话,只要header带上RequestVerificationToken即可,什么值都可以,为空也行,所以就是没用,倒是可以自己写一个
如果需要手动验证可以使用[AbpValidateAntiForgeryToken]标识控制器的函数
Abp vNext Token 结束
这个说实话,写的有点水,主要是懒了,理解就行,摆了


浙公网安备 33010602011771号