流控、认证、审计、授权以上都做了初步的简单的实现。


之前写的代码,base64加密了用户名和密码。
缺点1:每次请求都要带用户名密码 增加了泄露的风险。


每次传上来用户名和密码都要check验证。check是个非常耗资源的事

基于token的身份认证

token是有实效的

对于java开发,最常见的实现

代码实现来验证请求的流程

userController内增加login登陆的方法。

 @GetMapping("/login")
public void login(@Validated UserInfo user,HttpServletRequest request){
UserInfo info = userService.login(user);
request.getSession().setAttribute("user",user);
}

userService内增加login方法

UserInfo login(UserInfo user);

实现类实现login的方法

 @Override
public UserInfo login(UserInfo info) {
UserInfo result=null;
User user=userRepository.findByUsername(info.getUsername());
if(user!=null && SCryptUtil.check(info.getPassword(),user.getPassword())){
result=user.buildInfo();
}
return result;
}

因为之前做的授权的拦截器,把所有的请求都给拦截了。修改登陆时候我们不需要拦截,

定义一个数组,把不需要拦截的url放在数组内。

请求的路径如果不在我们的数组内就执行原来访问控制的逻辑。

如果是登陆的路径的话,不判断Attribute是否存在user了,也不判断请求的方法是否有权限了。直接返回true

private String[] permitUrls=new String[] {"/users/login"};
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println();
boolean result=true;
if(!ArrayUtils.contains(permitUrls,request.getRequestURI())){
User user=(User)request.getAttribute("user");
if (user==null){
response.setContentType("text/plain");
response.getWriter().write("need authentication");
response.setStatus(HttpStatus.UNAUTHORIZED.value());
return false;
}else{
String method = request.getMethod();
if(!user.hasPermission(method)){
response.setContentType("text/plain");
response.getWriter().write("forbidden");
response.setStatus(HttpStatus.FORBIDDEN.value());
return false;
}
}
} return result;
}

启动服务进行测试

先调用获取用户信息的服务,返回了401,没有带身份认证信息。

http://localhost:8080/users/13

下面来调用一下login的方法,传入用户名和密码

这个方法返回了200.里面的Reponse Headers里面。Set-Cookies里面写的JSESSIONID

类似于下面这种:

Set-Cookie:
JSESSIONID=A0C5DF8537D2E42D9542774AB18EBCDF; Path=/; HttpOnly

在chrome的设置里面




这就是我们存起来的 服务器返回的token

session有了信息了 再去访问

我们可以看发出去的请求里面 Cookie里面有JSessionID,刚才浏览器里面存的JSessionID就从这里发出去了。

也就是这里的第四部,第五步

以上就是session的原理。你要明白的是,基于cookie、session的本质上仍然还是基于token的认证方式。只不过他的这种认证方式是servlet规范里面已经都实现好了的。有优点也有缺点,客户端只存一个串,真的信息是存在服务器端的,另外一个优点就是使用起来很方便,因为所有的东西servlet容器都替你实现好了,你啥都不用管了,代码里只需要getSession()然后往里面放东西就可以了。验证的时候只需要从里面拿,然后验证就可以了。使用起来非常的方便
缺点:只针对浏览器起作用,因为我返回的Repoonse Header,浏览器收到这个Repoonse Header然后自个去设置cookie这件事只有浏览器支持。如果你是一个客户或者app 甚至一个第三方的应用,你是走不了这个机制的。 当服务器向浏览器传输cookie的时候,很容易被劫持。并不是绝对安全的。在大型的项目中,我们的servlet容器。服务器往往不是一台,如果一个用户的信息落在第一台服务,那么后面请求在访问的是第二台服务器。那么后面的就访问不到这个用户信息了。然后又要重新登陆。Spring 有一个Spring Session外部的存储来当你的Token Store来存session信息。以前没有Spring Session 要做这个事情还是挺麻烦的,要在好多个tomcat之间同步session信息,然后保持他们的一致性,

所以出现了另外一种自己实现来基于token 的登陆

基于cookie和sesison常见的风险。也就是一些攻击方式,以及怎么去防护这些攻击

结束

最新文章

  1. Andriod如何更改应用程序小图标
  2. 修改Mysql默认编码
  3. Sublime Text 插件 & 使用技巧
  4. Spring shiro使用
  5. Windows Azure公有云服务相关方案
  6. struts2 与 OGNL 表达式,jsp中 利用ognl 在valuestack中取值
  7. 把python文件编译成exe文件
  8. wildfly10报错2:ID注释有错
  9. javascript深入理解-从作用域链理解闭包
  10. Android视频录制从不入门到入门系列教程(二)————显示视频图像
  11. linux中去掉^M的方法
  12. etcd 增减节点
  13. MYSQL中动态行数据转列数据
  14. MyEclipse和Eclipse
  15. drupal8 管理入门
  16. AJAX是什么?
  17. CKEDITOR的内容js转码,C#控制器解码接收
  18. day 11 大文件操作
  19. MySQL之explain 的type列 & Extra列
  20. cv 验证

热门文章

  1. destoon7.0的商业圈应用于6.0下修改方案
  2. wamp——添加多版本PHP
  3. iframe使用总结(实战)
  4. 指数基金介绍专栏(8):国企指数(H股指数)详细介绍,最新资料解析,看这一篇就够了
  5. SIGAI机器学习第十九集 随机森林
  6. learning java AWT 剪贴板 传递文本
  7. learning java Runtime类中的exec
  8. WSAStartup() - 使用方法
  9. UVA 11019 Matrix Matcher ( 二维字符串匹配, AC自动机 || 二维Hash )
  10. Springboot如何优雅的解决ajax+自定义headers的跨域请求[转]