码迷,mamicode.com
首页 > 编程语言 > 详细

springboot之Jwt验证

时间:2017-11-17 11:53:58      阅读:1013      评论:0      收藏:0      [点我收藏+]

标签:时间   adapter   cat   log   集成   ace   system   addheader   end   

简介

什么是JWT(Json Web Token)

jwt是为了在网络应用环境间传递声明而执行的一种基于json的开放标准。该token被设计紧凑且安全的,特别适用于SSO场景。
jwt的声明一般被用来在身份提供者和服务提供者之间传递被认证的用户身份信息。

JWT长什么样

eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0MDAyIiwiZXhwIjoxNTEwOTcwMjU4fQ._FOqy5l44hODu3DjXh762LNUTLNQH15fdCUerdseDpmSKgkVSCjOyxQNTBKDSh3N-c83_pdEw5t6BdorgRU_kw

JWT的构成

JWT通常由三部分组成,头信息(header)、消息体(body)、签名(signature)
头信息指定了JWT使用的签名算法

header={alg=HS512}

消息体包含了JWT的意图,exp为令牌过期时间

body={sub=testUsername, exp=1510886546}

签名通过私钥生成

signature=kwq8a_B6WMqHOrEi-gFR5rRPmPL7qoShZJn0VFfXpXc1Yfw6BfVrliAP9C4UnXlqD3wRXO3mw_DDIdglN5lH9Q

使用springboot集成jwt

jwt官网

springboot官网

引用依赖

  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
  </dependency>

  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
  </dependency>

  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-actuator</artifactId>
  </dependency>

  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-devtools</artifactId>
  </dependency>

  <dependency>
      <groupId>io.jsonwebtoken</groupId>
      <artifactId>jjwt</artifactId>
      <version>0.7.0</version>
  </dependency>

构建普通rest接口

  @RestController
  @RequestMapping("/employee")
  public class EmployeeController {

      @GetMapping("/greeting")
       public String greeting() {
           return "Hello,World!";
       }
   }

JwtLoginFilter

public class JwtLoginFilter extends UsernamePasswordAuthenticationFilter {

   private AuthenticationManager authenticationManager;

   public JwtLoginFilter(AuthenticationManager authenticationManager) {
       this.authenticationManager = authenticationManager;
   }

  @Override
  public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
        throws AuthenticationException {
      Employee employee = new Employee();
       return authenticationManager.authenticate(
               new UsernamePasswordAuthenticationToken(
                   employee.getUsername(),
                   employee.getPassword(),
                   new ArrayList<>()
              )
       );
   }

  @Override
  protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, 
   FilterChain chain, Authentication authResult) throws IOException, ServletException {
      String token = Jwts.builder()
           .setSubject(((User) authResult.getPrincipal()).getUsername())
           .setExpiration(new Date(System.currentTimeMillis() + 30 * 60 * 1000))
           .signWith(SignatureAlgorithm.HS512, "JWTSecret")
           .compact();

       response.addHeader("Authorization", JwtUtils.getTokenHeader(token));
  }

}

JwtAuthenticationFilter

  public class JwtAuthenticationFilter extends BasicAuthenticationFilter {

  public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
      super(authenticationManager);
  }

  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
      String header = request.getHeader("Authorization");

      if (header == null || !header.startsWith(JwtUtils.getAuthorizationHeaderPrefix())) {
          chain.doFilter(request, response);
         return;
      }

      UsernamePasswordAuthenticationToken authenticationToken = getUsernamePasswordAuthenticationToken(header);

      SecurityContextHolder.getContext().setAuthentication(authenticationToken);
      chain.doFilter(request, response);
  }

  private UsernamePasswordAuthenticationToken getUsernamePasswordAuthenticationToken(String token) {
      String user = Jwts.parser()
              .setSigningKey("PrivateSecret")
              .parseClaimsJws(token.replace(JwtUtils.getAuthorizationHeaderPrefix(), ""))
              .getBody()
              .getSubject();

      if (null != user) {
          return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
      }

      return null;
  }
  }

SecurityConfiguration

  @Configuration
  @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
  public class SecurityConfiguration extends WebSecurityConfigurerAdapter {


    @Override
    public void configure(WebSecurity web) throws Exception {
          super.configure(web);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
      http.cors().and().csrf().disable().authorizeRequests()
              .anyRequest().authenticated()
              .and()
              .addFilter(new JwtLoginFilter(authenticationManager()))
              .addFilter(new JwtAuthenticationFilter(authenticationManager()));
    }

  }

使用postman测试

首先我们先测试/employee/greeting 响应如下:

{
"timestamp": 1510887634904,
"status": 403,
"error": "Forbidden",
"message": "Access Denied",
"path": "/employee/greeting"
}

很明显,状态码为403,此刻我们如果先登录拿到token后再测试呢,测试如下

技术分享

登录成功后,我们可以看到headers中已经带有jwt

authorization →Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0VXNlcm5hbWUiLCJleHAiOjE1MTA4ODkxMDd9.FtdEM0p84ff5CzDcoiQhtm1MF_NfDH2Ij1jspxlTQhuCISIzYdoU40OsFoxam9F1EXeVw2GZdQmArVwMk6HO1A

由于postman在一般情况下不支持自定义header 这个时候我们需要下载一个插件开启interceptor 开启后将authorization 放入header继续测试:
技术分享

技术分享

这时我们发现已经成功返回hello,world!

最后附上代码GitHub地址:源码下载

springboot之Jwt验证

标签:时间   adapter   cat   log   集成   ace   system   addheader   end   

原文地址:http://www.cnblogs.com/huyunfan/p/7850680.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!