mirror of https://github.com/elunez/eladmin
理清了SpringSecurity的执行过程,自动生成Entity转Dto的@Mappper注解的作用
parent
fa1d4f6f06
commit
a92198a836
|
@ -45,7 +45,7 @@ public class LogAspect {
|
|||
|
||||
/**
|
||||
* 配置环绕通知,使用在方法logPointcut()上注册的切入点
|
||||
*
|
||||
* 也可以使用@Around("@annotation(me.zhengjie.aop.log.Log)")
|
||||
* @param joinPoint join point for advice
|
||||
*/
|
||||
@Around("logPointcut()")
|
||||
|
|
|
@ -4,11 +4,16 @@ import lombok.Data;
|
|||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
/**
|
||||
* Jwt参数配置
|
||||
* @author Zheng Jie
|
||||
* @date 2019年11月28日
|
||||
* ConfigurationProperties可以将外部配置文件(比如applicaition.properties)加载进来,填充对象的对应字段的数据,然后供其他Bean使用
|
||||
* Configuration配置类注解,被自动扫描发现,不然这个类无法被Spring容器管理,会导致ConfigurationProperties失效
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
|
|
|
@ -94,10 +94,16 @@ public class AuthController {
|
|||
if (StringUtils.isBlank(authUser.getCode()) || !authUser.getCode().equalsIgnoreCase(code)) {
|
||||
throw new BadRequestException("验证码错误");
|
||||
}
|
||||
/**
|
||||
* 这是一个Authentication对象;,principal存储用户名,credentials存储密码,
|
||||
* 然后将authenticationToken对象提交到SpringSecurity去验证authenticate(authenticationToken)
|
||||
* 可通过boolean isAuthenticated()方法来决定该Authentication是否认证成功
|
||||
*/
|
||||
UsernamePasswordAuthenticationToken authenticationToken =
|
||||
new UsernamePasswordAuthenticationToken(authUser.getUsername(), password);
|
||||
/**
|
||||
* 通过token获得授权对象
|
||||
*
|
||||
*/
|
||||
Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
|
|
|
@ -21,6 +21,7 @@ public class TokenConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFi
|
|||
TokenFilter customFilter = new TokenFilter(tokenProvider);
|
||||
/**
|
||||
* 在验证用户名和密码之前,添加一个自定义的filter,用来提供token的验证
|
||||
* 每次访问方法的时候,先验证token是否有效,token有效再放开filter链,判断对应用户是否有权限访问受保护的资源
|
||||
*/
|
||||
http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ import java.io.IOException;
|
|||
|
||||
/**
|
||||
* @author /
|
||||
* GenericFilterBean的工作流程是:init-doFilter-destory,其中的init和destory在该类中实现,doFilter在具体实现类中实现
|
||||
* 我认为这里使用GenericFilterBean的原因是它刚好满足作为过滤器的条件,使用它不需要去实现其他不必要的方法
|
||||
*/
|
||||
@Slf4j
|
||||
public class TokenFilter extends GenericFilterBean {
|
||||
|
@ -33,17 +35,27 @@ public class TokenFilter extends GenericFilterBean {
|
|||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
|
||||
throws IOException, ServletException {
|
||||
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
|
||||
//从request中提取token中的密文
|
||||
String token = resolveToken(httpServletRequest);
|
||||
String requestRri = httpServletRequest.getRequestURI();
|
||||
// 验证 token 是否存在
|
||||
OnlineUser onlineUser = null;
|
||||
try {
|
||||
/**
|
||||
* TokenFilter不被Spring容器管理(类名上没有对应的组件注解),所以用不了Spring的自动注入
|
||||
* 只能使用反射手动的去加载
|
||||
*/
|
||||
SecurityProperties properties = SpringContextHolder.getBean(SecurityProperties.class);
|
||||
OnlineUserService onlineUserService = SpringContextHolder.getBean(OnlineUserService.class);
|
||||
//从redis中获取在线用户
|
||||
onlineUser = onlineUserService.getOne(properties.getOnlineKey() + token);
|
||||
} catch (ExpiredJwtException e) {
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
if (onlineUser != null && StringUtils.hasText(token) && tokenProvider.validateToken(token)) {
|
||||
Authentication authentication = tokenProvider.getAuthentication(token);
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
|
@ -54,6 +66,7 @@ public class TokenFilter extends GenericFilterBean {
|
|||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
|
||||
//提取token,token格式:Bearer空格+一串密文
|
||||
private String resolveToken(HttpServletRequest request) {
|
||||
SecurityProperties properties = SpringContextHolder.getBean(SecurityProperties.class);
|
||||
String bearerToken = request.getHeader(properties.getHeader());
|
||||
|
|
|
@ -37,6 +37,12 @@ public class TokenProvider implements InitializingBean {
|
|||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
/**
|
||||
* 解析配置文件里面的base64-secret字段,生成一个字节数组
|
||||
* 使用HMAC-SHA算法对字节数组进行运算得到SecretKey(Key的子类)
|
||||
* 生成签名的时候使用的秘钥secret,这个方法本地封装了的,一般可以从本地配置文件中读取,切记这个秘钥不能外露哦。
|
||||
* 它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。
|
||||
*/
|
||||
byte[] keyBytes = Decoders.BASE64.decode(properties.getBase64Secret());
|
||||
this.key = Keys.hmacShaKeyFor(keyBytes);
|
||||
}
|
||||
|
@ -48,7 +54,9 @@ public class TokenProvider implements InitializingBean {
|
|||
|
||||
long now = (new Date()).getTime();
|
||||
Date validity = new Date(now + properties.getTokenValidityInSeconds());
|
||||
|
||||
/**
|
||||
* 使用HmacSHA512加密
|
||||
*/
|
||||
return Jwts.builder()
|
||||
.setSubject(authentication.getName())
|
||||
.claim(AUTHORITIES_KEY, authorities)
|
||||
|
|
|
@ -9,6 +9,12 @@ import org.mapstruct.ReportingPolicy;
|
|||
/**
|
||||
* @author Zheng Jie
|
||||
* @date 2018-12-17
|
||||
* componentModel不写即为default,需要使用Mappers.getMapper(Class)获取对应Mapper的实例对象
|
||||
* componentModel为spring的时候,可使用Spring的自动注入
|
||||
* unmappedTargetPolicy在映射方法的目标对象(Target)的属性未填充源值(Source)的情况下应用的默认报告策略,支持的值 :
|
||||
* 1> ERROR : 任何未映射的目标属性都将导致映射代码生成失败
|
||||
* 2> WARN : 任何未映射的目标属性将在构建时引发警告
|
||||
* 3> IGNORE : 未映射的目标属性被忽略
|
||||
*/
|
||||
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||
public interface MenuMapper extends BaseMapper<MenuDto, Menu> {
|
||||
|
|
|
@ -46,7 +46,7 @@ jwt:
|
|||
header: Authorization
|
||||
# 令牌前缀
|
||||
token-start-with: Bearer
|
||||
# 必须使用最少88位的Base64对该令牌进行编码
|
||||
# 必须使用最少88位的Base64对该令牌进行编码,可以通过这个加密的密文生成服务器存储的秘钥
|
||||
base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI=
|
||||
# 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
|
||||
token-validity-in-seconds: 14400000
|
||||
|
|
Loading…
Reference in New Issue