对比两种承载认证信息的方式: 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. css中attribute selector及pseudo class

    https://developer.mozilla.org/en-US/docs/Web/CSS/Reference#Selectors 在css3规范中,定义了以下几种类型的selector: Ba ...

  2. 【Leetcode】【Medium】Linked List Cycle II

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null. 解题: ...

  3. 架设Git服务器

    架设Git服务器项目 Git Candy:http://github.com/Aimeast/GitCandy/ AE大神的作品, Git Candy© 是一个基于ASP.NET MVC的Git分布式 ...

  4. oracle客户端plsql安装

    1.确认版本 自己的操作系统版本(32位还是64位),oracle instant client(oracle客户端版本)和plsql版本 我自己的版本是:oracle客户端版本 64位,plsql ...

  5. CentOS 系统新装每次必看,直到背下。。

    1.CentOS7 mini 修改网卡信息: vi /etc/sysconfig/network-scripts/ifcfg-ens192 ONBOOT = yes vi /etc/resolv.co ...

  6. January 22 2017 Week 4 Sunday

    Dare and the world always yields. 大胆挑战,世界总会让步. Try it if you dare. If you want to change, if you wan ...

  7. stl sort使用不当造成崩溃

    #include <iostream>#include <vector>#include <algorithm>using namespace std; bool ...

  8. 使用redux开发的简单步骤

    一.安装redux包 npm install redux --save 二.根据APP数据结构或者后台请求的数据结构拟定state的大致结构. 可以把state写成一个对象字面量,放在reducer文 ...

  9. Redis配置文件(1)units/includes/GENERAL/SECURITY/LIMITS

    redis.conf文件 在Linux进行文件的查看! units单位: # Note on units: when memory size is needed, it is possible to ...

  10. MyBatis(9)整合spring

    具体的感兴趣可以参考:MyBatis 此时此刻,没用的话不再多说了,直接开始代码工程吧! 整体的代码实现: 具体使用到的我们在进行细说 基本上理解一边就能会使用整合  准备工作:  db.proper ...