spring boot 集成jwt security
文章结构
开门见山 数据流程
开门见山
这一部分直接展示代码,及将哪些代码进行修改就可以直接移值到自己的项目进行安全验证
代码目录结构
Auth
AuthController LoginUser
JWT
JwtUtil
Security
AuthFilter SecurityConfig UserDetailsImpl UserDetailsServiceImpl
User
UserController UserService User UserRepository
AuthController
说明:该类是自定义的用户进行登录验证获取token 的接口,是所有人都能访问的
package demo.demo1.auth.api.rest;
import demo.demo1.User.model.User; import
demo.demo1.User.service.UserService; import
demo.demo1.auth.jwt.JwtUtil; import demo.demo1.auth.model.LoginUser;
import io.swagger.annotations.Api; import
io.swagger.annotations.ApiOperation; import
io.swagger.annotations.ApiParam; import
org.springframework.beans.factory.annotation.Autowired; import
org.springframework.security.authentication.AuthenticationManager;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.validation.annotation.Validated; import
org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletResponse;
@RestController @RequestMapping("/auth") @CrossOrigin(origins = “*”)
@Api(
value = “/auth”,
description = “用户登录认证” ) public class AuthController {@Autowired private UserService userService; @Autowired private JwtUtil jwtUtil; @Autowired private AuthenticationManager authenticationManager; @RequestMapping(value = "", method = RequestMethod.POST) @ApiOperation( value = "登录", produces = "application/json" ) public void login( @ApiParam(value = "登录用户名/密码", name = "LoginUser", required = true) @Validated @RequestBody LoginUser loginUser, HttpServletResponse response) throws Exception { try { /** 通过security验证登录账号是否正确,这里直接将用户和密码传入security就好, * 不需要在这里进行验证,你的验证会在userDetailService中由security帮你进行 */ authenticationManager.authenticate( new UsernamePasswordAuthenticationToken( loginUser.getUsername(), loginUser.getPassword() ) ); } catch (AuthenticationException e) { throw new Exception("Username or Password error."); } // 验证通过后返回一个token值在http head中 User user = userService.getUserByUserName(loginUser.getUsername()); String token = jwtUtil.generateToken(user); // set token to header response.setHeader(JwtUtil.HEADER_STRING, token); } }
LoginUser
说明: 该类是你进行登录时的bean,这里主要就是为了和user进行区分,登录的时候用这个
bean package demo.demo1.auth.model;
import io.swagger.annotations.ApiModel;
import javax.validation.constraints.NotNull;
@ApiModel(value = “Login User”, description = “登录用户信息”) public class
LoginUser {@NotNull private String username; @NotNull private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
JwtUtil
说明:这个类就是依据你的登录用户生成jwt token,验证/解析请求时的token
package demo.demo1.auth.jwt;
import demo.demo1.User.model.User; import
demo.demo1.User.service.UserService; import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts; import
io.jsonwebtoken.SignatureAlgorithm; import
org.springframework.beans.factory.annotation.Autowired; import
org.springframework.beans.factory.annotation.Value; import
org.springframework.stereotype.Component;import java.util.Date; import java.util.HashMap; import java.util.Map;
import java.util.UUID;@Component public class JwtUtil {
/** token前缀 */ public static final String TOKEN_PREFIX = "Bearer "; /** * 设置http head中Authorization字段为token */ public static final String HEADER_STRING = "Authorization"; @Value("${jwt.secret}") private String secret; @Value("${jwt.expiration}") private Long expiration; @Autowired private UserService userService; /** * 依据登录的账号生成token */ public String generateToken(User user) throws Exception { if (user == null || user.getId() == null) { throw new Exception(String.format("user %s not valid", user)); } //设置token参数 Map<String, Object> claims = new HashMap<>(); claims.put("sub", user.getId()); claims.put("aud", "web"); claims.put("iss", "demo"); claims.put("iat", new Date()); return JwtUtil.TOKEN_PREFI