对比两种承载认证信息的方式: session vs token

token验证方案:

session验证方案:

session即会话是将用户信息保存在服务端,根据请求携带的session_id,从服务端存储(通常是redis)里提取出session。token即令牌是将用户信息保存在请求中,不过是加密后的值,在服务端需要对token进行解密,从而提取用户信息。

浅尝JWT(JSON WEB TOKEN)

JWT的使用场景:

authentication: 这是JWT最常见的应用场景。当用户登陆之后,接下来的每个请求都会携带这个JWT信息。单点登录基本上使用它。

information exchange: JWT是一种安全的多点之间信息传输的方式,因为它使用了签名。

JWT的构成:

  • Header
  • Payload
  • Signature

因此一个JWT看上去是长这样的:

xxxxxx.yyyyy.zzzzzz

在此之前,我们将用户登陆后的认证信息保存在SecurityContextHolder中,用户登陆信息保存在ThreadLocal中,理论上不能保证同一用户下一个请求是否被挡。这里将之前提到的Spring security认证方式改成使用token进行认证。

@Slf4j
public class PasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private AuthenticationManager authenticationManager; PasswordAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
} @Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
log.info("hello");
try {
AbstractAuthenticationToken authRequest = buildAuthentication(request);
return this.authenticationManager.authenticate(authRequest);
} catch (Exception failed) {
throw new AuthenticationFailedException("认证失败");
}
} @Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
FilterChain chain, Authentication authResult) throws IOException, ServletException {
response.addHeader("Authorization", "abcdefg");
} private AbstractAuthenticationToken buildAuthentication(HttpServletRequest request) throws IOException {
LoginInfo loginInfo = new ObjectMapper().readValue(request.getInputStream(), LoginInfo.class);
log.info("login info is " + loginInfo);
return new UsernameAndPasswordAuthenticationToken(loginInfo.getName(), loginInfo.getPassword());
}
}

这个filter extends UsernamePasswordAuthenticationFilter, 默认只对url为/login的请求进行登陆认证。

认证成功之后,在请求头部加token信息。下次请求来的时候,会有一个TokenAuthenticationFilter对token进行验证。

这里随意用了一个token,该token没有携带用户信息,只用来验证是否有权限访问请求。

public class TokenAuthenticationFilter extends BasicAuthenticationFilter {

public TokenAuthenticationFilter(AuthenticationManager authenticationManager) {
super(authenticationManager);
} @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String token = request.getHeader("Authorization");
if(!token.equals("abcdefg")) {
filterChain.doFilter(request, response);
} else {
UsernameAndPasswordAuthenticationToken usernameAndPasswordAuthenticationToken = new UsernameAndPasswordAuthenticationToken();
usernameAndPasswordAuthenticationToken.setAuthenticated(true);
SecurityContextHolder.getContext().setAuthentication(usernameAndPasswordAuthenticationToken);
filterChain.doFilter(request, response);
} }
}

如果我们header里不带token,返回结果是403 forbidden。

如果携带token就能成功访问请求api了。

接下来使用JWT来创建和使用token。

在PasswordAuthenticationFilter认证成功之后,生成一个jwt存在请求返回头里。

在TokenAuthenticationFilter的filter流程中,首先增加jwt校验:

然后就实现了使用jwt的方式认证。

代码git repo: https://github.com/Rying/twitter-clone.git

参考:

https://blog.csdn.net/sxdtzhaoxinguo/article/details/77965226

https://github.com/auth0/java-jwt

Spring security学习笔记(二)的更多相关文章

  1. SpringBoot + Spring Security 学习笔记(五)实现短信验证码+登录功能

    在 Spring Security 中基于表单的认证模式,默认就是密码帐号登录认证,那么对于短信验证码+登录的方式,Spring Security 没有现成的接口可以使用,所以需要自己的封装一个类似的 ...

  2. SpringBoot + Spring Security 学习笔记(三)实现图片验证码认证

    整体实现逻辑 前端在登录页面时,自动从后台获取最新的验证码图片 服务器接收获取生成验证码请求,生成验证码和对应的图片,图片响应回前端,验证码保存一份到服务器的 session 中 前端用户登录时携带当 ...

  3. [转]Spring Security学习总结二

    原文链接: http://www.blogjava.net/redhatlinux/archive/2008/08/20/223148.html http://www.blogjava.net/red ...

  4. SpringBoot + Spring Security 学习笔记(二)安全认证流程源码详解

    用户认证流程 UsernamePasswordAuthenticationFilter 我们直接来看UsernamePasswordAuthenticationFilter类, public clas ...

  5. Spring Security学习笔记一

    一.使用Spring Security 1.在pom 文件中添加Spring Security的依赖. <dependency> <groupId>org.springfram ...

  6. Spring Security学习笔记

    Spring Web Security是Java web开发领域的一个认证(Authentication)/授权(Authorisation)框架,基于Servlet技术,更确切的说是基于Servle ...

  7. SpringBoot + Spring Security 学习笔记(一)自定义基本使用及个性化登录配置

    官方文档参考,5.1.2 中文参考文档,4.1 中文参考文档,4.1 官方文档中文翻译与源码解读 SpringSecurity 核心功能: 认证(你是谁) 授权(你能干什么) 攻击防护(防止伪造身份) ...

  8. Spring Security学习笔记(三)

    之前提到过认证后怎么存放用户信息,令牌token是一种方式,session是另一种方式,这里介绍使用spring session data redis存储httpSession. 添加了以上依赖后,我 ...

  9. Spring Security学习笔记(一)

    认证和权限控制 AuthenticationManager是认证的主要接口,它只有一个authenticate方法,可以做3件事情. 返回一个认证信息(Authentication),表示认证成功 抛 ...

随机推荐

  1. Java在Web开发语言上败给了PHP(转)

    PHP的主要语言开发者之一.Zend公司的创始人之一Andi Gutmans最近在blog中直言不讳地批评了Java语言.他指出,目前Java厂商试图在JVM上提供动态语言实现的路子根本不对,Java ...

  2. qt 拷贝文件设置进度条

    /** * @brief FuncModuleWin::copyFile * @param fromFIleName 优盘里面的文件 * @param toFileName 拷贝到/bin里面的启动文 ...

  3. 安装Access Database Engine后,提示未注册Microsoft.ACE.OLEDB.12.0

    未注册Microsoft.ACE.OLEDB.12.0 ,下载安装 Microsoft Access Database Engine:https://www.microsoft.com/en-us/d ...

  4. The FLARE On Challenge

    上周才开始做这个CTF,用一周左右的时间完成了全部7道题.算是为即将到来的找工作进行热身和学习,下面记录一下遇到的问题和学到的东西,具体的解题过程就不详细描述了. challenge1 这道题用IDA ...

  5. June 19th 2017 Week 25th Monday

    Everyone is dissatisfied with his own fortune. 人对自己的命运总是感到不满足. We always want more, even when we hav ...

  6. January 18 2017 Week 3 Wednesday

    True liberty is to have power over oneself in all things. 真正的自由是在所有的事情上都能控制住自己. Liberty isn't meanin ...

  7. 一些SAP Partners能够通过二次开发实现打通C/4HANA和S/4HANA的方法介绍

    有好几位朋友在公众号后台给我留言询问SAP C/4HANA和S/4HANA集成的方案. 尽管我给这些朋友推送了一个方案:打通C/4HANA和S/4HANA的一个原型开发:智能服务创新案例,然而我得到的 ...

  8. 邮件营销巧妙添加GIF让您的邮件动起来

    动态图片远比静态图片要吸引人,因此近年来,一些营销人员也开始越来越频繁的使用GIF动画图片,适当的穿插和点缀动态图片,能够生动形象的表达出 主题,并且时不时令读者忍俊不禁.尤其是做邮件营销的,如果能在 ...

  9. SQLi-db 批量注入工具+教程

    这款工具在中国还没人发.所以我发来给大家玩玩:顺便带了教程. 关键字:inurl:article.asp?id= inurl:article.php?id=inurl:article.jsp?id=( ...

  10. MySQL的存储函数(自定义函数)的定义和使用方法

    存储函数 什么是存储函数: 封装一段sql代码,完成一种特定的功能,返回结果. 存储函数的语法:  create function 函数([函数参数[,….]]) Returns 返回类型 Begin ...