zoukankan      html  css  js  c++  java
  • Spring security学习笔记(二)

    对比两种承载认证信息的方式: 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

  • 相关阅读:
    7月的尾巴,你是XXX
    戏说Android view 工作流程《下》
    “燕子”
    Android开机动画bootanimation.zip
    戏说Android view 工作流程《上》
    ViewController里已连接的IBOutlet为什么会是nil
    My first App "Encrypt Wheel" is Ready to Download!
    iOS开发中角色Role所产生的悲剧(未完)
    UIScrollView实现不全屏分页的小技巧
    Apple misunderstood my app,now my app status changed to “In Review”
  • 原文地址:https://www.cnblogs.com/holiday2000/p/9673807.html
Copyright © 2011-2022 走看看