当前位置:首页 » JAVA技术教程

【spring cloud】自定义jwt实现spring cloud nosession

2017-08-23 07:01 本站整理 浏览(11)

image

路由实现在Zuul,网关的路由默认配置。
jwt 生成、验证依赖

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

最核心的配置是在spring security中加入我们token校验机制的fiter:JwtAuthenticationTokenFilter

protected void doFilterInternal(
    HttpServletRequest request,
    HttpServletResponse response,
    FilterChain chain) throws ServletException, IOException {
    String authHeader = request.getHeader(this.tokenHeader);
    if (authHeader != null && authHeader.startsWith(tokenHead)) {
        String authToken = authHeader.substring(tokenHead.length()); // The part after "Bearer "
        String username = jwtTokenUtil.getUsernameFromToken(authToken);
        logger.info("checking authentication " + username);

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);

            if (jwtTokenUtil.validateToken(authToken, userDetails)) {
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(
                        request));
                logger.info("authenticated user " + username + ", setting security context");
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }
    }

    chain.doFilter(request, response);
}

在看我们的spring security 配置

protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
    // 由于使用的是JWT,我们这里不需要csrf
    .csrf().disable()

    .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()

    // 基于token,所以不需要session
    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()

    .authorizeRequests()
    //.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()

    // 允许对于网站静态资源的无授权访问
    .antMatchers(
            HttpMethod.GET,
            "/",
            "/*.html",
            "/favicon.ico",
            "/**/*.html",
            "/**/*.css",
            "/**/*.js"
    ).permitAll()
    .antMatchers("/auth/**").permitAll()
    .anyRequest().authenticated();
// 添加JWT filter
httpSecurity
        .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
// 禁用缓存
httpSecurity.headers().cacheControl();
}

获取token

POST 

http://localhost:8080/auth

Content-Type: application/json

{"username":"1234","password":"1234"}

---
结果

{
  "token" : "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxMjM0IiwiY3JlYXRlZCI6MTUwMzQxMzMwODkxOCwiZXhwIjoxNTA0MDE4MTA4fQ.jQc5MRdgKfi5ds1N0ZSsxkunQQVkFuGJ7Giv1_JrjTiKsu3h7UwE8vjU5wVPaipM_zkbHaMpRqXvF__ci5p7aw"
}

访问资源

GET

http://localhost:8080/user-service/bizUser/getUserScore

Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxMjM0IiwiY3JlYXRlZCI6MTUwMzQxMzMwODkxOCwiZXhwIjoxNTA0MDE4MTA4fQ.jQc5MRdgKfi5ds1N0ZSsxkunQQVkFuGJ7Giv1_JrjTiKsu3h7UwE8vjU5wVPaipM_zkbHaMpRqXvF__ci5p7aw

---
结果
[
  {
    "id": 11,
    "username": "123",
    "password": "456",
    "scoreList": [
      {
        "id": 1,
        "score": 100
      }
    ]
  }
]

不加认证token

{
  "timestamp": 1503413947608,
  "status": 401,
  "error": "Unauthorized",
  "message": "手动滑稽(  ´-ω ・)▄︻┻┳══━一",
  "path": "/user-service/bizUser/getUserScore"
}

参考https://github.com/wpcfan/spring-boot-tut

详细整合源码:springcloud-zuul-jwt 和 springboot-mybatis-plus