JWT认证授权功能完善
This commit is contained in:
parent
cd1dd9190a
commit
b0a945d242
@ -27,7 +27,7 @@ public class BindingResultAspect {
|
|||||||
if (arg instanceof BindingResult) {
|
if (arg instanceof BindingResult) {
|
||||||
BindingResult result = (BindingResult) arg;
|
BindingResult result = (BindingResult) arg;
|
||||||
if (result.hasErrors()) {
|
if (result.hasErrors()) {
|
||||||
return new CommonResult().validateFailed(result.getFieldError().getDefaultMessage());
|
return new CommonResult().validateFailed(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import org.springframework.context.annotation.Bean;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
|
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
|
||||||
|
import org.springframework.security.authentication.encoding.PasswordEncoder;
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
@ -48,7 +49,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
"/v2/api-docs/**"
|
"/v2/api-docs/**"
|
||||||
)
|
)
|
||||||
.permitAll()
|
.permitAll()
|
||||||
.antMatchers("/auth/**")// 对于获取token的rest api要允许匿名访问
|
.antMatchers("/admin/**")// 对于获取token的rest api要允许匿名访问
|
||||||
.permitAll()
|
.permitAll()
|
||||||
.anyRequest()// 除上面外的所有请求全部需要鉴权认证
|
.anyRequest()// 除上面外的所有请求全部需要鉴权认证
|
||||||
.authenticated();
|
.authenticated();
|
||||||
@ -61,7 +62,12 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
@Override
|
@Override
|
||||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
auth.userDetailsService(userDetailsService())
|
auth.userDetailsService(userDetailsService())
|
||||||
.passwordEncoder(new Md5PasswordEncoder());
|
.passwordEncoder(passwordEncoder());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PasswordEncoder passwordEncoder(){
|
||||||
|
return new Md5PasswordEncoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
package com.macro.mall.controller;
|
||||||
|
|
||||||
|
import com.macro.mall.dto.CommonResult;
|
||||||
|
import com.macro.mall.dto.UmsAdminLoginParam;
|
||||||
|
import com.macro.mall.dto.UmsAdminParam;
|
||||||
|
import com.macro.mall.model.UmsAdmin;
|
||||||
|
import com.macro.mall.service.UmsAdminService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后台用户管理
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
@Api(tags = "UmsAdminController", description = "后台用户管理")
|
||||||
|
@RequestMapping("/admin")
|
||||||
|
public class UmsAdminController {
|
||||||
|
@Autowired
|
||||||
|
private UmsAdminService adminService;
|
||||||
|
@Value("${jwt.tokenHeader}")
|
||||||
|
private String tokenHeader;
|
||||||
|
|
||||||
|
@ApiOperation(value = "用户注册")
|
||||||
|
@RequestMapping(value = "/register", method = RequestMethod.POST)
|
||||||
|
@ResponseBody
|
||||||
|
public Object register(@RequestBody UmsAdminParam umsAdminParam, BindingResult result) {
|
||||||
|
UmsAdmin umsAdmin = adminService.register(umsAdminParam);
|
||||||
|
if (umsAdmin == null) {
|
||||||
|
new CommonResult().failed();
|
||||||
|
}
|
||||||
|
return new CommonResult().success(umsAdmin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "登录以后返回token")
|
||||||
|
@RequestMapping(value = "/login", method = RequestMethod.POST)
|
||||||
|
@ResponseBody
|
||||||
|
public Object login(@RequestBody UmsAdminLoginParam umsAdminLoginParam, BindingResult result) {
|
||||||
|
String token = adminService.login(umsAdminLoginParam.getUsername(), umsAdminLoginParam.getPassword());
|
||||||
|
if (token == null) {
|
||||||
|
new CommonResult().failed();
|
||||||
|
}
|
||||||
|
return new CommonResult().success(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "刷新token")
|
||||||
|
@RequestMapping(value = "/token/refresh", method = RequestMethod.GET)
|
||||||
|
@ResponseBody
|
||||||
|
public Object refreshToken(HttpServletRequest request) {
|
||||||
|
String token = request.getHeader(tokenHeader);
|
||||||
|
String refreshToken = adminService.refreshToken(token);
|
||||||
|
if (refreshToken == null) {
|
||||||
|
return new CommonResult().failed();
|
||||||
|
}
|
||||||
|
return new CommonResult().success(token);
|
||||||
|
}
|
||||||
|
}
|
@ -11,7 +11,6 @@ import javax.validation.constraints.NotNull;
|
|||||||
/**
|
/**
|
||||||
* 品牌传递参数
|
* 品牌传递参数
|
||||||
*/
|
*/
|
||||||
@ApiModel(value = "PmsBrandParam")
|
|
||||||
public class PmsBrandParam {
|
public class PmsBrandParam {
|
||||||
@ApiModelProperty(value = "品牌名称",required = true)
|
@ApiModelProperty(value = "品牌名称",required = true)
|
||||||
@NotEmpty(message = "名称不能为空")
|
@NotEmpty(message = "名称不能为空")
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.macro.mall.dto;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import org.hibernate.validator.constraints.NotEmpty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户登录参数
|
||||||
|
*/
|
||||||
|
public class UmsAdminLoginParam {
|
||||||
|
@ApiModelProperty(value = "用户名", required = true)
|
||||||
|
@NotEmpty(message = "用户名不能为空")
|
||||||
|
private String username;
|
||||||
|
@ApiModelProperty(value = "密码", required = true)
|
||||||
|
@NotEmpty(message = "密码不能为空")
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package com.macro.mall.dto;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import org.hibernate.validator.constraints.Email;
|
||||||
|
import org.hibernate.validator.constraints.NotEmpty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户登录参数
|
||||||
|
*/
|
||||||
|
public class UmsAdminParam {
|
||||||
|
@ApiModelProperty(value = "用户名", required = true)
|
||||||
|
@NotEmpty(message = "用户名不能为空")
|
||||||
|
private String username;
|
||||||
|
@ApiModelProperty(value = "密码", required = true)
|
||||||
|
@NotEmpty(message = "密码不能为空")
|
||||||
|
private String password;
|
||||||
|
@ApiModelProperty(value = "用户头像")
|
||||||
|
private String icon;
|
||||||
|
@ApiModelProperty(value = "邮箱")
|
||||||
|
@Email(message = "邮箱格式不合法")
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIcon() {
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIcon(String icon) {
|
||||||
|
this.icon = icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package com.macro.mall.service;
|
package com.macro.mall.service;
|
||||||
|
|
||||||
|
import com.macro.mall.dto.UmsAdminParam;
|
||||||
import com.macro.mall.model.UmsAdmin;
|
import com.macro.mall.model.UmsAdmin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -10,4 +11,23 @@ public interface UmsAdminService {
|
|||||||
* 根据用户名获取后台管理员
|
* 根据用户名获取后台管理员
|
||||||
*/
|
*/
|
||||||
UmsAdmin getAdminByUsername(String username);
|
UmsAdmin getAdminByUsername(String username);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册功能
|
||||||
|
*/
|
||||||
|
UmsAdmin register(UmsAdminParam umsAdminParam);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录功能
|
||||||
|
* @param username 用户名
|
||||||
|
* @param password 密码
|
||||||
|
* @return 生成的JWT的token
|
||||||
|
*/
|
||||||
|
String login(String username,String password);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新token的功能
|
||||||
|
* @param oldToken 旧的token
|
||||||
|
*/
|
||||||
|
String refreshToken(String oldToken);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,21 @@
|
|||||||
package com.macro.mall.service.impl;
|
package com.macro.mall.service.impl;
|
||||||
|
|
||||||
|
import com.macro.mall.dto.UmsAdminParam;
|
||||||
import com.macro.mall.mapper.UmsAdminMapper;
|
import com.macro.mall.mapper.UmsAdminMapper;
|
||||||
import com.macro.mall.model.UmsAdmin;
|
import com.macro.mall.model.UmsAdmin;
|
||||||
import com.macro.mall.model.UmsAdminExample;
|
import com.macro.mall.model.UmsAdminExample;
|
||||||
import com.macro.mall.service.UmsAdminService;
|
import com.macro.mall.service.UmsAdminService;
|
||||||
|
import com.macro.mall.util.JwtTokenUtil;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.authentication.encoding.PasswordEncoder;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -16,6 +27,17 @@ import java.util.List;
|
|||||||
public class UmsAdminServiceImpl implements UmsAdminService{
|
public class UmsAdminServiceImpl implements UmsAdminService{
|
||||||
@Autowired
|
@Autowired
|
||||||
private UmsAdminMapper adminMapper;
|
private UmsAdminMapper adminMapper;
|
||||||
|
@Autowired
|
||||||
|
private AuthenticationManager authenticationManager;
|
||||||
|
@Autowired
|
||||||
|
private UserDetailsService userDetailsService;
|
||||||
|
@Autowired
|
||||||
|
private JwtTokenUtil jwtTokenUtil;
|
||||||
|
@Autowired
|
||||||
|
private PasswordEncoder passwordEncoder;
|
||||||
|
@Value("${jwt.tokenHead}")
|
||||||
|
private String tokenHead;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UmsAdmin getAdminByUsername(String username) {
|
public UmsAdmin getAdminByUsername(String username) {
|
||||||
UmsAdminExample example = new UmsAdminExample();
|
UmsAdminExample example = new UmsAdminExample();
|
||||||
@ -26,4 +48,40 @@ public class UmsAdminServiceImpl implements UmsAdminService{
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UmsAdmin register(UmsAdminParam umsAdminParam) {
|
||||||
|
UmsAdmin umsAdmin = new UmsAdmin();
|
||||||
|
BeanUtils.copyProperties(umsAdminParam,umsAdmin);
|
||||||
|
//查询是否有相同用户名的用户
|
||||||
|
UmsAdminExample example = new UmsAdminExample();
|
||||||
|
example.createCriteria().andUsernameEqualTo(umsAdmin.getUsername());
|
||||||
|
List<UmsAdmin> umsAdminList = adminMapper.selectByExample(example);
|
||||||
|
if(umsAdminList.size()>0){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//将密码进行加密操作
|
||||||
|
String md5Password = passwordEncoder.encodePassword(umsAdmin.getPassword(), null);
|
||||||
|
umsAdmin.setPassword(md5Password);
|
||||||
|
adminMapper.insert(umsAdmin);
|
||||||
|
return umsAdmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String login(String username, String password) {
|
||||||
|
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username,password);
|
||||||
|
Authentication authentication = authenticationManager.authenticate(authenticationToken);
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||||
|
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
|
||||||
|
return jwtTokenUtil.generateToken(userDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String refreshToken(String oldToken) {
|
||||||
|
String token = oldToken.substring(tokenHead.length());
|
||||||
|
if(jwtTokenUtil.canRefresh(token)){
|
||||||
|
return jwtTokenUtil.refreshToken(token);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
package com.macro.mall.util;
|
package com.macro.mall.util;
|
||||||
|
|
||||||
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.*;
|
||||||
import io.jsonwebtoken.Jwts;
|
import org.slf4j.Logger;
|
||||||
import io.jsonwebtoken.SignatureAlgorithm;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -22,6 +23,7 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class JwtTokenUtil {
|
public class JwtTokenUtil {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(JwtTokenUtil.class);
|
||||||
private static final String CLAIM_KEY_USERNAME = "sub";
|
private static final String CLAIM_KEY_USERNAME = "sub";
|
||||||
private static final String CLAIM_KEY_CREATED = "created";
|
private static final String CLAIM_KEY_CREATED = "created";
|
||||||
@Value("${jwt.secret}")
|
@Value("${jwt.secret}")
|
||||||
@ -32,26 +34,26 @@ public class JwtTokenUtil {
|
|||||||
/**
|
/**
|
||||||
* 根据负责生成JWT的token
|
* 根据负责生成JWT的token
|
||||||
*/
|
*/
|
||||||
String generateToken(Map<String, Object> claims) {
|
private String generateToken(Map<String, Object> claims) {
|
||||||
return Jwts.builder()
|
return Jwts.builder()
|
||||||
.setClaims(claims)
|
.setClaims(claims)
|
||||||
.setExpiration(generateExpirationDate())
|
.setExpiration(generateExpirationDate())
|
||||||
.signWith(SignatureAlgorithm.RS512, secret)
|
.signWith(SignatureAlgorithm.HS512, secret)
|
||||||
.compact();
|
.compact();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从token中获取JWT中的负载
|
* 从token中获取JWT中的负载
|
||||||
*/
|
*/
|
||||||
Claims getClaimsFromToken(String token) {
|
private Claims getClaimsFromToken(String token) {
|
||||||
Claims claims;
|
Claims claims = null;
|
||||||
try {
|
try {
|
||||||
claims = Jwts.parser()
|
claims = Jwts.parser()
|
||||||
.setSigningKey(secret)
|
.setSigningKey(secret)
|
||||||
.parseClaimsJws(token)
|
.parseClaimsJws(token)
|
||||||
.getBody();
|
.getBody();
|
||||||
} finally {
|
} catch (Exception e) {
|
||||||
claims = null;
|
LOGGER.info("JWT格式验证失败:{}",token);
|
||||||
}
|
}
|
||||||
return claims;
|
return claims;
|
||||||
}
|
}
|
||||||
@ -70,9 +72,8 @@ public class JwtTokenUtil {
|
|||||||
String username;
|
String username;
|
||||||
try {
|
try {
|
||||||
Claims claims = getClaimsFromToken(token);
|
Claims claims = getClaimsFromToken(token);
|
||||||
username = claims.getSubject();
|
username = claims.getSubject();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
|
||||||
username = null;
|
username = null;
|
||||||
}
|
}
|
||||||
return username;
|
return username;
|
||||||
@ -101,14 +102,33 @@ public class JwtTokenUtil {
|
|||||||
* 从token中获取过期时间
|
* 从token中获取过期时间
|
||||||
*/
|
*/
|
||||||
private Date getExpiredDateFromToken(String token) {
|
private Date getExpiredDateFromToken(String token) {
|
||||||
Date expiredDate = null;
|
Claims claims = getClaimsFromToken(token);
|
||||||
try {
|
return claims.getExpiration();
|
||||||
Claims claims = getClaimsFromToken(token);
|
|
||||||
expiredDate = claims.getExpiration();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return expiredDate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户信息生成token
|
||||||
|
*/
|
||||||
|
public String generateToken(UserDetails userDetails) {
|
||||||
|
Map<String, Object> claims = new HashMap<>();
|
||||||
|
claims.put(CLAIM_KEY_USERNAME, userDetails.getUsername());
|
||||||
|
claims.put(CLAIM_KEY_CREATED, new Date());
|
||||||
|
return generateToken(claims);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断token是否可以被刷新
|
||||||
|
*/
|
||||||
|
public boolean canRefresh(String token) {
|
||||||
|
return !isTokenExpired(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新token
|
||||||
|
*/
|
||||||
|
public String refreshToken(String token) {
|
||||||
|
Claims claims = getClaimsFromToken(token);
|
||||||
|
claims.put(CLAIM_KEY_CREATED, new Date());
|
||||||
|
return generateToken(claims);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,8 @@ spring.thymeleaf.cache=false
|
|||||||
jwt.tokenHeader=Authorization
|
jwt.tokenHeader=Authorization
|
||||||
#JWT加解密使用的密钥
|
#JWT加解密使用的密钥
|
||||||
jwt.secret=mySecret
|
jwt.secret=mySecret
|
||||||
#JWT的超期限时间
|
#JWT的超期限时间(60*60*24)
|
||||||
jwt.expiration=604800
|
jwt.expiration=604800
|
||||||
#JWT负载中拿到开头
|
#JWT负载中拿到开头
|
||||||
jwt.tokenHead="Bearer "
|
jwt.tokenHead=Bearer
|
||||||
#===JWT end===
|
#===JWT end===
|
Loading…
x
Reference in New Issue
Block a user