博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
授权中心
阅读量:2390 次
发布时间:2019-05-10

本文共 4832 字,大约阅读时间需要 16 分钟。

leyou-user

无状态登陆

在服务器端保存session无状态不需要session,把登陆状态保存在cookie中

无状态登录的流程:

  • 当客户端第一次请求服务时,服务端对用户进行信息认证(登录)
  • 认证通过,将用户信息进行加密形成token,返回给客户端,作为登录凭证
  • 以后每次请求,客户端都携带认证的token
  • 服务的对token进行解密,判断是否有效。
  • token的安全性:JWT + RSA非对称加密
    在这里插入图片描述

JWT + RSA非对称加密

token:登陆时,jwt oath2 jwt:头信息(jwt) 载荷(用户信息,签发人 签发时间 有效时间) 签名(头信息+载荷:通过加密算法生成。作用:校验前两部分内容的合法性)

zuul网关访问的流程

在这里插入图片描述

  • 我们首先利用RSA生成公钥和私钥。私钥保存在授权中心,公钥保存在Zuul和各个信任的微服务
  • 用户请求登录
  • 授权中心校验,通过后用私钥对JWT进行签名加密
  • 返回jwt给用户
  • 用户携带JWT访问
  • Zuul直接通过公钥解密JWT,进行验证,验证通过则放行
  • 请求到达微服务,微服务直接用公钥解析JWT,获取用户信息,无需访问授权中心

搭建授权中心

聚合工程:leyou-auth-common(jwt相关的工具类) leyou-auth-service(微服务)
  • 用户鉴权:
    • 接收用户的登录请求,通过用户中心的接口进行校验,通过后生成JWT
    • 使用私钥生成JWT并返回
  • 服务鉴权:微服务间的调用不经过Zuul,会有风险,需要鉴权中心进行认证
    • 原理与用户鉴权类似,但逻辑稍微复杂一些(此处我们不做实现)

因为生成jwt,解析jwt这样的行为以后在其它微服务中也会用到,因此我们会抽取成工具。我们把鉴权中心进行聚合,一个工具module,一个提供服务的module

在这里插入图片描述
在这里插入图片描述

编写登录授权接口

在leyou-auth-servcice编写一个接口,对外提供登录授权服务。基本流程如下:

  • 客户端携带用户名和密码请求登录
  • 授权中心调用用户中心接口,根据用户名和密码查询用户信息
  • 如果用户名密码正确,能获取用户,否则为空,则登录失败
  • 如果校验成功,则生成JWT并返回

jwtUtils

根据载荷还有私钥生成jwt类型的token根据公钥解析jwt类型的token,获取载荷信息(userInfo)rsaUtils(生成公钥和私钥文件,并且读取公钥和私钥文件返回公钥和私钥对象)

登陆功能

1.调用user-service中的queryUser接口,验证用户是否正确2.判断返回的用户信息是否为空3.生成jwt类型的token4.token信息设置到cookie中

首页用户名回显

1.获取Cookie中jwt类型的token @CookieValue("LY_TOKEN")2.jwtUtils解析jwt,获取用户信息	判断用户是否为空3.刷新jwt时间 cookie时间4.响应用户信息

在zuul网关添加过滤器

在Zuul编写拦截器,对用户的token进行校验,如果发现未登录,则进行拦截。

在这里插入图片描述

编写过滤器逻辑

基本逻辑:

  • 获取cookie中的token
  • 通过JWT对token进行校验
  • 通过:则放行;不通过:则重定向到登录页
    在这里插入图片描述
@Component@EnableConfigurationProperties(JwtProperties.class)public class LoginFilter extends ZuulFilter {
@Autowired private JwtProperties properties; @Override public String filterType() {
return "pre"; } @Override public int filterOrder() {
return 5; } @Override public boolean shouldFilter() {
return true; } @Override public Object run() throws ZuulException {
// 获取上下文 RequestContext context = RequestContext.getCurrentContext(); // 获取request HttpServletRequest request = context.getRequest(); // 获取token String token = CookieUtils.getCookieValue(request, this.properties.getCookieName()); // 校验 try {
// 校验通过什么都不做,即放行 JwtUtils.getInfoFromToken(token, this.properties.getPublicKey()); } catch (Exception e) {
// 校验出现异常,返回403 context.setSendZuulResponse(false); context.setResponseStatusCode(HttpStatus.FORBIDDEN.value()); } return null; }}

白名单;

并不是所有的路径我们都需要拦截,例如:

  • 登录校验接口:/auth/**
  • 注册接口:/user/register
  • 数据校验接口:/user/check/**
  • 发送验证码接口:/user/code
  • 搜索接口:/search/**

另外,跟后台管理相关的接口,因为我们没有做登录和权限,因此暂时都放行,但是生产环境中要做登录校验:

  • 后台商品服务:/item/**

所以,我们需要在拦截时,配置一个白名单,如果在名单内,则不进行拦截。

在application.yaml中添加规则:

leyou:  filter:    allowPaths:      - /api/auth      - /api/search      - /api/user/register      - /api/user/check      - /api/user/code      - /api/item

然后读取这些属性:在这里插入图片描述

@ConfigurationProperties(prefix = "leyou.filter")public class FilterProperties {
private List
allowPaths; public List
getAllowPaths() {
return allowPaths; } public void setAllowPaths(List
allowPaths) {
this.allowPaths = allowPaths; }}

在过滤器中的shouldFilter方法中添加判断逻辑

@Component@EnableConfigurationProperties({
JwtProperties.class, FilterProperties.class})public class LoginFilter extends ZuulFilter {
@Autowired private JwtProperties jwtProp; @Autowired private FilterProperties filterProp; private static final Logger logger = LoggerFactory.getLogger(LoginFilter.class); @Override public String filterType() {
return "pre"; } @Override public int filterOrder() {
return 5; } @Override public boolean shouldFilter() {
// 获取上下文 RequestContext ctx = RequestContext.getCurrentContext(); // 获取request HttpServletRequest req = ctx.getRequest(); // 获取路径 String requestURI = req.getRequestURI(); // 判断白名单 // 遍历允许访问的路径 for (String path : this.filterProp.getAllowPaths()) {
// 然后判断是否是符合 if(requestURI.startsWith(path)){
return false; } } return true; } @Override public Object run() throws ZuulException {
// 获取上下文 RequestContext ctx = RequestContext.getCurrentContext(); // 获取request HttpServletRequest request = ctx.getRequest(); // 获取token String token = CookieUtils.getCookieValue(request, jwtProp.getCookieName()); // 校验 try {
// 校验通过什么都不做,即放行 JwtUtils.getInfoFromToken(token, jwtProp.getPublicKey()); } catch (Exception e) {
// 校验出现异常,返回403 ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(403); logger.error("非法访问,未登录,地址:{}", request.getRemoteHost(), e ); } return null; }}

转载地址:http://vxxab.baihongyu.com/

你可能感兴趣的文章
ffmpeg系列:使用ffmpeg转换为RGB数据并缩放视频
查看>>
能Ping通外网但就是不能打开所有网页的解决办法
查看>>
windows7配置虚拟AP的脚本
查看>>
北京开放政府信息资源 “大数据”供社会化利用
查看>>
大数据挖掘变革 美赛达软硬云引领车联网商业蓝海
查看>>
停车费上涨需要公开“大数据”
查看>>
DirectFB代码导读
查看>>
Cocos2dx3.2从零开始【四】继续。
查看>>
sphinx教程2__安装、配置和使用
查看>>
Discuz!$_G变量的使用方法
查看>>
Windows资源管理器相关信息获取
查看>>
windows资源管理器及ie监听
查看>>
No module named 'Crypto'
查看>>
常用openstack的镜像下载及密码
查看>>
详解python中的浅拷贝和深拷贝
查看>>
详解python中闭包和装饰器
查看>>
修改openstack云主机的IP地址
查看>>
ubuntu系统的定制裁剪(适用于嵌入式瘦客户端)
查看>>
嵌入式之系统移植详解(linux)
查看>>
openstack之 glance_image和instances存储目录解析
查看>>