commit message

This commit is contained in:
Chopper
2021-05-13 10:41:46 +08:00
commit 3785bdb3bb
1424 changed files with 100110 additions and 0 deletions

View File

@@ -0,0 +1,104 @@
package cn.lili.security;
import cn.hutool.core.util.StrUtil;
import cn.lili.common.cache.Cache;
import cn.lili.common.cache.CachePrefix;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.enums.SecurityEnum;
import cn.lili.common.security.enums.UserEnums;
import cn.lili.common.token.SecretKeyUtil;
import cn.lili.common.utils.ResponseUtil;
import com.google.gson.Gson;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
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.ArrayList;
import java.util.List;
/**
* @author Chopper
*/
@Slf4j
public class StoreAuthenticationFilter extends BasicAuthenticationFilter {
private final Cache cache;
public StoreAuthenticationFilter(AuthenticationManager authenticationManager,
Cache cache) {
super(authenticationManager);
this.cache = cache;
}
@SneakyThrows
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
String accessToken = request.getHeader(SecurityEnum.HEADER_TOKEN.getValue());
if (StrUtil.isBlank(accessToken)) {
chain.doFilter(request, response);
return;
}
try {
UsernamePasswordAuthenticationToken authentication = getAuthentication(accessToken, response);
SecurityContextHolder.getContext().setAuthentication(authentication);
} catch (Exception e) {
log.error(e.getMessage());
}
chain.doFilter(request, response);
}
/**
* 获取token信息
*
* @param jwt
* @param response
* @return
*/
private UsernamePasswordAuthenticationToken getAuthentication(String jwt, HttpServletResponse response) {
try {
Claims claims
= Jwts.parser()
.setSigningKey(SecretKeyUtil.generalKeyByDecoders())
.parseClaimsJws(jwt).getBody();
//获取存储在claims中的用户信息
String json = claims.get(SecurityEnum.USER_CONTEXT.getValue()).toString();
AuthUser authUser = new Gson().fromJson(json, AuthUser.class);
// 校验redis中是否有权限
if (cache.hasKey(CachePrefix.ACCESS_TOKEN.getPrefix(UserEnums.STORE) + jwt)) {
//用户角色
List<GrantedAuthority> auths = new ArrayList<>();
auths.add(new SimpleGrantedAuthority("ROLE_" + authUser.getRole().name()));
//构造返回信息
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(authUser.getUsername(), null, auths);
authentication.setDetails(authUser);
return authentication;
}
ResponseUtil.output(response, 403, ResponseUtil.resultMap(false, 403, "登录已失效,请重新登录"));
return null;
} catch (ExpiredJwtException e) {
log.debug("user analysis exception:", e);
} catch (Exception e) {
log.error("user analysis exception:", e);
}
return null;
}
}

View File

@@ -0,0 +1,81 @@
package cn.lili.security;
import cn.lili.common.cache.Cache;
import cn.lili.common.security.CustomAccessDeniedHandler;
import cn.lili.common.utils.SpringContextUtil;
import cn.lili.config.properties.IgnoredUrlsProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.web.cors.CorsConfigurationSource;
/**
* spring Security 核心配置类 Store安全配置中心
*
* @author Chopper
* @date 2020/11/14 16:20
*/
@Slf4j
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class StoreSecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 忽略验权配置
*/
private final IgnoredUrlsProperties ignoredUrlsProperties;
/**
* spring security -》 权限不足处理
*/
private final CustomAccessDeniedHandler accessDeniedHandler;
private final Cache<String> cache;
@Override
protected void configure(HttpSecurity http) throws Exception {
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http
.authorizeRequests();
// 配置的url 不需要授权
for (String url : ignoredUrlsProperties.getUrls()) {
registry.antMatchers(url).permitAll();
}
registry.and()
// 禁止网页iframe
.headers().frameOptions().disable()
.and()
.logout()
.permitAll()
.and()
.authorizeRequests()
// 任何请求
.anyRequest()
// 需要身份认证
.authenticated()
.and()
// 允许跨域
.cors().configurationSource((CorsConfigurationSource) SpringContextUtil.getBean("corsConfigurationSource")).and()
// 关闭跨站请求防护
.csrf().disable()
// 前后端分离采用JWT 不需要session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
// 自定义权限拒绝处理类
.exceptionHandling().accessDeniedHandler(accessDeniedHandler)
.and()
// 添加JWT认证过滤器
.addFilter(new StoreAuthenticationFilter(authenticationManager(), cache));
}
}