Spring Boot使用JWT实现系统登陆验证

简介

什么是JWT(Json Web Token)

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

JWT长什么样

eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0MDAyIiwiZXhwIjoxNTEwOTcwMjU4fQ._FOqy5l44hODu3DjXh762LNUTLNQH15fdCUerdseDpmSKgkVSCjOyxQNTBKDSh3N-c83_pdEw5t6BdorgRU_kwjava

JWT的构成

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

header={alg=HS512}github

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

body={sub=testUsername, exp=1510886546}算法

签名经过私钥生成spring

signature=kwq8a_B6WMqHOrEi-gFR5rRPmPL7qoShZJn0VFfXpXc1Yfw6BfVrliAP9C4UnXlqD3wRXO3mw_DDIdglN5lH9Qdjango

使用springboot集成jwt

jwt官网json

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后再测试呢,测试以下

postman-test1

登陆成功后,咱们能够看到headers中已经带有jwt

authorization →Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0VXNlcm5hbWUiLCJleHAiOjE1MTA4ODkxMDd9.FtdEM0p84ff5CzDcoiQhtm1MF_NfDH2Ij1jspxlTQhuCISIzYdoU40OsFoxam9F1EXeVw2GZdQmArVwMk6HO1A

因为postman在通常状况下不支持自定义header 这个时候咱们须要下载一个插件开启interceptor 开启后将authorization 放入header继续测试:
postman-test3

postman-test2

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

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

 

本文转载自

原文做者:胡运凡

原文连接:http://www.javashuo.com/article/p-dtbkgbgk-o.html

相关文章
相关标签/搜索