JWT实现在网关模块,网关的路由是默认配置。 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"
}