对比两种承载认证信息的方式: 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. idea 出现 java.lang.OutOfMemoryError: PermGen space

    今天在项目启动时候,刚刚启动 就 报了 Exception in thread "http-bio-8080-exec-1" 之后 出现了 java.lang.OutOfMemor ...

  2. div浮层,滚动条移动,保持位置不变的4种方法

    div浮层,滚动条移动,保持位置不变的4种方法 div在顶部不变.滚动条滚动,div还是在顶部! 直接上传源码 了: 方法一: <!DOCTYPE html PUBLIC "-//W3 ...

  3. skype for business server 2015 报错“不可用:试图检查架构状态时发生故障,请确保能够访问Active Direcotry”

    报错“不可用:试图检查架构状态时发生故障,请确保能够访问Active Direcotry” 遇到错误后就上网查询了下,有的人说用下面方法解决了 用域的administrator 登入就可以了(之前是用 ...

  4. 图的存储结构(邻接矩阵与邻接表)及其C++实现

    一.图的定义 图是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为: G=(V,E) 其中:G表示一个图,V是图G中顶点的集合,E是图G中顶点之间边的集合. 注: 在线性表中,元素个数可以为零, ...

  5. laravel5.5 自定义验证规则——手机验证RULE

    相信很多小伙伴和我一样烦恼,laravel没有自带手机号的验证,每次验证手机号都要写正则这类的规则,每次都是repeat yourself!违背了编码的一个原则,就是Don't repeat your ...

  6. Windows文件批量重命名

    选择要命名的文件 按F2,编辑名字 然后按回车就行了 电视剧命名,我认为这样足够了

  7. CodeIgniter框架学习要点

    以下内容从兄弟连的CI教学视频中摘抄: http://codeigniter.org.cn/tutorials/ ------------------------------------------- ...

  8. Yii 多表关联relations

    1,首先多表关联是在models/xx.php的relations里配置的.而且是互配,但有区别.格式:'VarName'=>array('RelationType', 'ClassName', ...

  9. UVa 11582 - Colossal Fibonacci Numbers!(数论)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  10. SqlMapConfig.xml配置文件

    SqlMapConfig.xml中配置的内容和顺序如下: 1.1 properties(属性) mybatis的属性加载顺序.读取顺序:properties------>resource或url ...