API安全


SSO 单点登录(Single sign-on)是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统

jwt(Json Web Token)

引入jwt

jwt的特点

  1. 自包含:开始都是通过DefaultTokenServicec创建了一个默认的token实现,它是生成一个无意义的uuid,然后将用户信息保存在外部存储中。但是JWT本身就可以包含用户信息,无需外部存储
  2. 密签:通过密钥防止其他人篡改,不能保存密码等敏感信息
  3. 可扩展:自定义用户信息
    实现:
    之前是通过在资源服务器配置 自定义的RedisTokenStore
    现在是通过在资源服务器配置 创建一个jwtTokenStore,需要传入jwt转换器,对jwt进行签名。

JsonWebToken.io网站 可以解析access_token的信息
通过jwt获取登陆信息时,是通过jwt的信息查询出一个SpringSecurityAuthentication实例,而不是原生jwt信息

扩展jwt信息

实现TokenEnhancer接口重写enhance方法向jwt添加额外信息,然后将其注入到Spring容器中,然后配置认证服务器让其使用增强器。通过增强器链将jwt转换器 和 jwt增强器连接起来。
但是查询登陆用户信息时,增强器添加的信息是查不到的。
解决: 用户加入jjwt依赖,然后通过jwt解析器解析 自定义用户信息。 系统只会解析默认jwt实现的信息

通过refresh_token刷新令牌

当用户访问时,若access_token快超时了,则通过refresh_token发请求换取新得acess_token,延长token有效时间。
refresh_token一般比access_token的超时时间长,一般为一周

使用jwt实现sso

在这里插入图片描述
发送的jwt不一样,但是能解析出相同的用户信息来。
解析并登录:解析jwt的authentication,然后放入SpringSecurityContext
应用A,B是前后端分离,应用B不负责处理逻辑,只负责处理页面渲染等操作——>通过jwt访问资源服务器
实现:
依赖:mvc,security,oauth,jwt

  1. 认证服务器
    a) 编写认证服务器配置类(@EnableAuthorizationServer),配置给哪些客户端发送令牌
    b) 注入JwtTokenStore,然后配置jwt转换器进行密签
    c) 配置访问tokenKey时,需要进行身份认证。tokenKey是客户端解析token时需要的密签
  2. 客户端1
    a) 在启动类添加注解@EnableOAuth2Sso
    b) 在配置类配置客户端账号,密码;配置跳转认证服务器的地址;配置请求令牌的地址;配置请求令牌密钥的地址(解析令牌)
  3. 客户端2
    a) 在启动类添加注解@EnableOAuth2Sso
    b) 在配置类配置客户端账号,密码;配置跳转认证服务器的地址;配置请求令牌的地址;配置请求令牌密钥的地址(解析令牌)
    待优化:1. 表单登陆 2. 登陆密码后需要手动点击认证按钮

CAS vs oauth2

OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的资源,而无需将用户名和密码提供给第三方应用。
SSO是一个让多个应用共享用户session的解决方案。目前市面上最流行的单点登录系统就是耶鲁大学开发的CAS系统,成为目前SSO的既定协议。

API安全

在这里插入图片描述

API安全的目标CIA

API安全涉及三方面的问题:网路安全+信息安全+应用安全

  1. 机密性(Confientiality):确保信息只被预期的读者访问
  2. 完整性(Integrity):防止未授权的创建,修改和删除
  3. 可用性(Availability):当用户访问API时,API总是可用的。

API的风险和解决

  1. API的风险:STRIDE
    Spoofing欺骗:伪装成某人。
    Tampering干预:不仅执行了自己的操作,还执行了其他人的操作。 比如改自己订单状态后,还改了女友的订单状态
    Repudiation否认:拒绝承认做过的事情
    Information disclosure信息泄露:看到保密的信息
    Denial of sevice拒绝服务:阻止用户访问信息和服务
    Elevation of privilege越权:做了未授权的操作
  2. API风险的防范
    认证(欺骗):确保用户是他自己
    授权(信息泄露/干预/越权):确保每个针对API的访问都是经过授权的
    审计(否认):确保所有操作都是被记录的
    流控(拒绝服务):防止过多请求淹没API
    加密(信息泄露):确保出入API的数据是私密的

防止注入攻击

注入攻击:select * from user where name=‘jojo’
select * from user where name=’ ’ 'or 1=1 ’
解决:使用#{}语法,Mybatis会自动生成PreparedStatement,使用参数绑定的方式来设置值 ${}则会进行字符串拼接

API风险的防范具体

在这里插入图片描述

流控 429太多请求

  1. 引入Guva依赖
  2. 实现一个过滤器,通过RateLimiter指定每分钟的请求数

认证

@data生成get,set方法
单一职责原则,服务user和认证user应该区分开 关注点分离
BeanUtils.copuProperties(info,user);
登陆vs认证
登陆:用户获取身份证明的过程,不合法就会返回错误
认证:验证用户身份是否合法,不管成功还是失败还是会向下走流程
|——HttpBase认证:Base64加密(username:password)——>将Authorization:Basic 字符串放入请求头

参数效验

400参数异常 500服务器内部错误

  1. 接口的参数效验:保证前端传入的数据正确
    常见类型都有对应的效验
    a) 实体类属性 @NotBlank(message=“用户密码不能为空”)
    b) 控制器参数 @Validated使用效验
  2. 数据库效验:保证后台逻辑处理正确
    @Column(unique=true) 数据库层面效验

密码加密

检查明文 和 加密串是否匹配
盐:保证密码相同,加密结果也不相同
md5:消息摘要算法,两个相同的密码加密结果也相同
SHA算法:

Http加密

  1. 验证通信双方的身份
  2. 对传输数据封装,加密
    实现: 一般在公司入口配成HTTPS,内部网配成HTTP
    a) 创建空文件,执行keytool -genkeypair -alias(名字) username -keyalg(生成算法) RSA -keystore(存储路径) path
    b) 应用配置https:server.ssl.key-store:classpath: leeqee.key 密钥存放路径
    server.ssl.key-store-password:123 keystore的密码
    server.ssl.key-password:123 密钥本身密码

审计日志

谁在什么时间干什么事,认证之后,授权之前
过滤器调整执行顺序@order(1)

使用JPA实现审计功能

  1. 创建审计日志实体类: username,method,path,status,createtime,modifytime
  2. 实现HandlerInterceptorAdaptor接口创建一个拦截器,重写prehandler在请求进来之前保存日志
    重写afterCompletition在请求返回之后保存日志
  3. 在mvc配置类中将拦截器配置进去(可配置拦截路径)
  4. 使用JPA自动支持审计功能:在配置类通过@EnableJpaAuditing启动JPA审计功能,在审计父类写@EntityListeners(AuditingEntityListener.class),然后使用现成的注解@CreatedDate @LastModifyDate实现相关功能

问题:
访问异常url,先响应一个200,然后响应一个500,这样不利于审计查看
解决:
通过@RestControllerAdavice使用全局异常处理,使用@ResponseStatus返回服务器响应错误

授权 401认证失败 403认证成功,但授权失败

RBAC(Role Based Access Control)基于角色的访问控制
ACL(Acess Control lists) 访问控制列表,用户和权限挂钩

登陆

用户只在第一次登陆时才需要进行登陆,但每次请求都会进行认证
怎么样防止用户每次访问都会进行验证密码操作
解决:使用基于token的身份认证,token映射用户名密码信息
实现:基于session的实现,基于cookie的实现
在这里插入图片描述
request.getSession().setAttribute(“username”,username); //将用户信息保存到session中,并已经启用了cookie-session交互逻辑。

sesison固定攻击

request.getSession() 根据sessionid从服务器找对应session,如果找到则认为已经登陆
问题:攻击者首先登陆获取session cookie,然后诱骗用户使用攻击者的session cookie进行登陆,将用户信息保存在了攻击者的中,攻击者的session中存放的就是用户的信息了,然后就可以伪造身份进行操作了

HttpSession session = request.getSession(false)
if(session!=null){
      session.invalidate();
}
request.getSession(true).setAttribute("user",user);
  1. 传入false参数,如果获取不到session就返回null
  2. 如果获取到session,则失效旧session,创建新session

状态码介绍

401:凭证无效被拒绝

402:服务器配置被拒绝

403:凭证有效但是没权限

404:访问资源不存在

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值