1.JWT是什么:Json web token
1.1如何使用token:
生成token:生成字符串
package com.sany.springjwt;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import lombok.extern.log4j.Log4j2;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.stream.Collectors;
//生成token
@Log4j2
public class JwtAuthenticateFilter extends UsernamePasswordAuthenticationFilter{
private static final String strKey = "YWCtaDEWw2bnImvE99lyxj+AtH/QD8UsZdK7vQW7ExY=";
private final AuthenticationManager authenticationManager;
public JwtAuthenticateFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
setFilterProcessesUrl("/api/token");
}
// 认证用户名密码
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
// String username =request.getParameter("username");
// String password =request.getParameter("password");
// UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken= new UsernamePasswordAuthenticationToken(username,password);
LoginData loginData = null;
try {
loginData = pareData(request);
} catch (IOException e) {
e.printStackTrace();
}
UsernamePasswordAuthenticationToken uToken= new UsernamePasswordAuthenticationToken(loginData.getUsername(),loginData.getPassword());
//true或false
return this.authenticationManager.authenticate(uToken);
}
//把token返回给客户
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
User user = (User)authResult.getPrincipal();
Object roles = user.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.toList());
String token = Jwts.builder()
.setHeaderParam("TYP","JWT")
.setIssuer("testIssuer")
.setAudience("testAudience")
.setExpiration(new Date(System.currentTimeMillis() + 10000000))
.setSubject(user.getUsername())
.setIssuedAt(new Date())
.claim("rol",roles)
.signWith(Keys.hmacShaKeyFor(strKey.getBytes())).compact();
response.setHeader("Authorization","Bearer "+ token);
}
private LoginData pareData(HttpServletRequest request) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(request.getInputStream(),LoginData.class);
}
}
鉴定token:识别字符串
package com.sany.springjwt;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import lombok.extern.log4j.Log4j2;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.util.StringUtils;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
//鉴定token
@Log4j2
public class JwtAuthorizationFilter extends BasicAuthenticationFilter {
public JwtAuthorizationFilter(AuthenticationManager authenticationManager){
super(authenticationManager);
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
Authentication authentication = getAuthentication(request);
if(authentication == null){
filterChain.doFilter(request,response);
return;
}
SecurityContextHolder.getContext().setAuthentication(authentication);
filterChain.doFilter(request,response);
}
private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request){
String token = request.getHeader(SecurityConstants.TOKEN_HEADER);
if(!StringUtils.isEmpty(token) && token.startsWith(SecurityConstants.TOKEN_PREFIX)){
try {
// 验证token
Object parsedToken = Jwts.parserBuilder()
.setSigningKey(SecurityConstants.JWT_SECRET.getBytes())
.build()
.parseClaimsJws(token.replace(SecurityConstants.TOKEN_PREFIX, ""));
String username = Jwts.parserBuilder()
.setSigningKey(SecurityConstants.JWT_SECRET.getBytes())
.build()
.parseClaimsJws(token.replace(SecurityConstants.TOKEN_PREFIX, ""))
.getBody()
.getSubject();
Object authorities = ((List<?>) Jwts.parserBuilder()
.setSigningKey(SecurityConstants.JWT_SECRET.getBytes())
.build()
.parseClaimsJws(token.replace(SecurityConstants.TOKEN_PREFIX, "")).getBody()
.get("rol")).stream()
.map(authority -> new SimpleGrantedAuthority((String) authority));
if (!StringUtils.isEmpty(username)) {
// return new UsernamePasswordAuthenticationToken(username, null, authorities);
return new UsernamePasswordAuthenticationToken(username, null, null);
}
}catch(ExpiredJwtException exception){
// log.warn("requewt:{}",token,exception.getMessage());
}
}
return null;
}
}
2.如何写pom.xml
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.1</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.1</version>
<scope>runtime</scope>
</dependency>
3.如何写SecurityConfig.java
package com.sany.springjwt;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/guest").permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic()
.and()
.addFilter(new JwtAuthenticateFilter(authenticationManager()))
.addFilter(new JwtAuthorizationFilter(authenticationManager()))
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
4.如何写JwtController
package com.sany.springjwt;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class JwtController {
@GetMapping("/api/guest")
public String guest() {
return "This is a guest api msg";
}
@GetMapping("/api/admin")
public String admin() {
return "This is a admin api msg";
}
}