前后端分离Oauth2.0 - springsecurity + spring-authorization-server —客户端凭证模式

序言

此次针对 客户端凭证模式 的实践和需求的介绍, 流程的讲解.

需求及场景

在业务系统中需要接收 租户客户的数据信息, 比如 品类信息, 员工信息. 此时我们不可能为每一个客户都进行定义一个接口进行维护其 数据的传输.

思路

我们需要定义出来一个 openApi平台, 提供统一的接入服务, 统一的接口, 为了之后不同的客户传输同一类型的数据做准备.

流程

  1. 客户需要在平台中进行申请 client信息, 我们进行颁发 client_id 和 client_security . 此时可以进行收费, 例如: 微信公众号自定义服务,需要 300元的开通费用.
  2. 在进行同步数据的时候, 可以通过 client_id 和 client_security 进行做客户信息的验证以及获取, 为之后的业务逻辑中使用, 例如: 传输的品类, 员工信息是哪个租户的, 为数据隔离做准备.
  3. post请求接口, https://www.authorization.life/auth-life/oauth2/token
    传参:
    grant_type: client_credentials – 验证方式.
    client_id: passport – 申请时的 client信息
    client_secret:3MMoCFo4nTNjRtGZ – 申请的密码明文
  4. 通过 验证通过之后将返回自定义的 access_token 信息.

配置 OAuth2TokenCustomizer 自定义 token


    /**
     * 将重写jwtToken的中的信息,并将其存储到redis中。
     *
     * @param context JwtEncodingContext
     */
    @Override
    public void customize(JwtEncodingContext context) {
        //此处的token字符串是前端拿到的jwtToken信息中解密后的字符串,在这里将自定义jwtToken的实现,将定制jwt的 header 和 claims,将此token存放到 claim 中
        String token = UUID.randomUUID().toString(true);
        RegisteredClient registeredClient = context.getRegisteredClient();
        UserDetail userDetail = null;
        // ***** 客户端凭证模式 的判断,匹配 client的Token信息. 
        if (principal instanceof OAuth2ClientAuthenticationToken) {
            //如果当前登录的是client,则进行封装client
            userDetail = securityAuthUserService.createUserDetailByClientId(registeredClient.getClientId());
        }
        //如果解析失败,则抛出异常信息。
        if (Objects.isNull(userDetail)) {
            log.error("在自定义token实现中, 用户信息解析异常。");
            userDetail = new UserDetail();
        }

        //也需要将此token存放到当前登录用户中,为了在退出登录时进行获取redis中的信息并将其删除
        userDetail.setToken(token);
        //将用户信息放置到redis中,并设置其过期时间为 client中的过期时间
        strRedisHelper.strSet(LifeSecurityConstants.getUserTokenKey(token), userDetail,
                registeredClient.getTokenSettings().getAccessTokenTimeToLive().getSeconds(), TimeUnit.SECONDS);
        log.info("生成的用户-token是-{},此token作为key,用户信息作为value存储到redis中", token);
        //也可以在此处将当前登录用户的信息存放到jwt中,但是这样就不再安全。
        context.getClaims().claim(LifeSecurityConstants.TOKEN, token).build();
    }

实践结果

前后端分离Oauth2.0 - springsecurity + spring-authorization-server —客户端凭证模式_第1张图片

github: https://github.com/qjyn1314/authorization-life

你可能感兴趣的:(spring-boot,gateway,spring,redis,java)