互联网安全架构三(互联网开放平台设计)

目录

 

互联网开放平台设计

1.需求:

2.常用解决办法:

实现使用令牌方式搭建搭建API开放平台

原理:

数据库表设计

获取AccessToken

编写拦截器拦截请求,验证accessToken

基于OAuth2.0协议方式

什么是OAuth

OAuth2.0总体处理流程


互联网开放平台设计

1.需求:

现在A公司与B公司进行合作,B公司需要调用A公司开放的外网接口获取数据,

如何保证外网开放接口的安全性。

2.常用解决办法

2.1 使用加签名方式,防止篡改数据

2.2 使用Https加密传输

2.3 搭建OAuth2.0认证授权

2.4 使用令牌方式

2.5 搭建网关实现黑名单和白名单

实现使用令牌方式搭建搭建API开放平台

原理:

为每个合作机构创建对应的appid、app_secret,生成对应的access_token(有效期2小时),在调用外网开放接口的时候,必须传递有效的access_token。

数据库表设计

 

CREATE TABLE `m_app` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `app_name` varchar(255) DEFAULT NULL,

  `app_id` varchar(255) DEFAULT NULL,

  `app_secret` varchar(255) DEFAULT NULL,

  `is_flag` varchar(255) DEFAULT NULL,

  `access_token` varchar(255) DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

 

App_Name     表示机构名称
App_ID  应用id
App_Secret  应用密钥  (可更改)
Is_flag  是否可用 (是否对某个机构开放)
access_token上一次access_token

 

 

        

 

         

 

 

获取AccessToken

// 创建获取getAccessToken

@RestController

@RequestMapping(value = "/auth")

public class AuthController extends BaseApiService {

      @Autowired

      private BaseRedisService baseRedisService;

      private long timeToken = 60 * 60 * 2;

      @Autowired

      private AppMapper appMapper;

 

      // 使用appId+appSecret 生成AccessToke

      @RequestMapping("/getAccessToken")

      public ResponseBase getAccessToken(AppEntity appEntity) {

            AppEntity appResult = appMapper.findApp(appEntity);

            if (appResult == null) {

                  return setResultError("没有对应机构的认证信息");

            }

            int isFlag = appResult.getIsFlag();

            if (isFlag == 1) {

                  return setResultError("您现在没有权限生成对应的AccessToken");

            }

            // ### 获取新的accessToken 之前删除之前老的accessToken

            // redis中删除之前的accessToken

            String accessToken = appResult.getAccessToken();

            baseRedisService.delKey(accessToken);

            // 生成的新的accessToken

            String newAccessToken = newAccessToken(appResult.getAppId());

            JSONObject jsonObject = new JSONObject();

            jsonObject.put("accessToken", newAccessToken);

            return setResultSuccessData(jsonObject);

      }

 

      private String newAccessToken(String appId) {

            // 使用appid+appsecret 生成对应的AccessToken 保存两个小时

            String accessToken = TokenUtils.getAccessToken();

            // 保证在同一个事物redis 事物中

            // 生成最新的token keyaccessToken value appid

            baseRedisService.setString(accessToken, appId, timeToken);

            // 表中保存当前accessToken

            appMapper.updateAccessToken(accessToken, appId);

            return accessToken;

      }

}

 

编写拦截器拦截请求,验证accessToken

 

//验证AccessToken 是否正确

@Component

public class AccessTokenInterceptor extends BaseApiService implements HandlerInterceptor {

      @Autowired

      private BaseRedisService baseRedisService;

 

      /**

       * 进入controller层之前拦截请求

       *

       * @param httpServletRequest

       * @param httpServletResponse

       * @param o

       * @return

       * @throws Exception

       */

 

      public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o)

                  throws Exception {

            System.out.println("---------------------开始进入请求地址拦截----------------------------");

            String accessToken = httpServletRequest.getParameter("accessToken");

            // 判断accessToken是否空

            if (StringUtils.isEmpty(accessToken)) {

                  // 参数Token accessToken

                  resultError(" this is parameter accessToken null ", httpServletResponse);

                  return false;

            }

            String appId = (String) baseRedisService.getString(accessToken);

            if (StringUtils.isEmpty(appId)) {

                  // accessToken 已经失效!

                  resultError(" this is  accessToken Invalid ", httpServletResponse);

                  return false;

            }

            // 正常执行业务逻辑...

            return true;

 

      }

 

      public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,

                  ModelAndView modelAndView) throws Exception {

            System.out.println("--------------处理请求完成后视图渲染之前的处理操作---------------");

      }

 

      public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,

                  Object o, Exception e) throws Exception {

            System.out.println("---------------视图渲染之后的操作-------------------------0");

      }

 

      // 返回错误提示

      public void resultError(String errorMsg, HttpServletResponse httpServletResponse) throws IOException {

            PrintWriter printWriter = httpServletResponse.getWriter();

            printWriter.write(new JSONObject().toJSONString(setResultError(errorMsg)));

      }

 

}

基于OAuth2.0协议方式

什么是OAuth

OAuth: OAuth(开放授权)是一个开放标准,允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的所有内容。

OAuth2.0

对于用户相关的OpenAPI(例如获取用户信息,动态同步,照片,日志,分享等),为了保护用户数据的安全和隐私,第三方网站访问用户数据前都需要显式的向用户征求授权。

QQ登录OAuth2.0采用OAuth2.0标准协议来进行用户身份验证和获取用户授权,相对于之前的OAuth1.0协议,其认证流程更简单和安全。

 

OAuth2.0总体处理流程

1 第一步:用户同意授权,获取code

2 第二步:通过code换取网页授权access_token

3 第三步:刷新access_token(如果需要)

4 第四步:拉取用户信息(需scope为 snsapi_userinfo)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值