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
参数是来自Bodyx-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.Hostappsettings.json中的AuthServer.Authority必须和IdentityServerappsettings.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的问题,localhost127.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_tokenrefresh_token的API,/connect/revocation
这个API接收两个参数tokentoken_type_hint,就是令牌和令牌类型
可以在后端调用这个API去撤销令牌,前端也可以
调用比较麻烦

  • client_idIdentityServerClients表的ClientId字段
  • client_secretIdentityServerClientSecrets表的Value字段,要对应ClientId

两种调用方式
不加验证,这样需要client_idclient_secret参数

加验证,把client_idclient_secret分别加入UsernamePassword,Body就不需要client_idclient_secret

其实这里并不能使access_token过期,只能使refresh_token过期,我试过了,因为jwt生成的token信息是固定的,单纯校验token信息是不够的,所以还是redis好使

双token策略

  • 在后端设置一个校验token的IAuthorizationFilter过滤器,检查token的有效期,到了差不多的时间就在response中设置一个标识,由前端校验这个
  • 在前端设置一个response拦截器,校验响应中是否具有标识,有标识则在请求中带上refresh_token,然后刷新本地access_tokenrefresh_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_tokenrefresh_token,那么原先的refresh_token仍然有效

如果需要access_tokenrefresh_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 结束

这个说实话,写的有点水,主要是懒了,理解就行,摆了

posted @ 2022-10-12 17:00  .NET好耶  阅读(2642)  评论(5编辑  收藏  举报