commit message
This commit is contained in:
136
manager-api/src/main/java/cn/lili/security/ManagerAuthenticationFilter.java
Executable file
136
manager-api/src/main/java/cn/lili/security/ManagerAuthenticationFilter.java
Executable file
@@ -0,0 +1,136 @@
|
||||
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.naming.NoPermissionException;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Chopper
|
||||
*/
|
||||
@Slf4j
|
||||
public class ManagerAuthenticationFilter extends BasicAuthenticationFilter {
|
||||
|
||||
private final Cache cache;
|
||||
|
||||
public ManagerAuthenticationFilter(AuthenticationManager authenticationManager,
|
||||
Cache cache) {
|
||||
super(authenticationManager);
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
|
||||
|
||||
//从header中获取jwt
|
||||
String jwt = request.getHeader(SecurityEnum.HEADER_TOKEN.getValue());
|
||||
// 如果没有token 则return
|
||||
if (StrUtil.isBlank(jwt)) {
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
//获取用户信息,存入context
|
||||
UsernamePasswordAuthenticationToken authentication = getAuthentication(jwt, response);
|
||||
//自定义权限过滤
|
||||
customAuthentication(request, response, authentication);
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义权限过滤
|
||||
*
|
||||
* @param request
|
||||
* @param authentication
|
||||
*/
|
||||
private void customAuthentication(HttpServletRequest request, HttpServletResponse response, UsernamePasswordAuthenticationToken authentication) throws NoPermissionException {
|
||||
AuthUser authUser = (AuthUser) authentication.getDetails();
|
||||
Map<String, List<String>> permission = (Map<String, List<String>>) cache.get(CachePrefix.PERMISSION_LIST.getPrefix(UserEnums.MANAGER) + authUser.getId());
|
||||
if (authUser.getIsSuper()) {
|
||||
return;
|
||||
} else {
|
||||
//用户是否拥有权限判定œ
|
||||
//获取数据权限
|
||||
// if (request.getMethod().equals(RequestMethod.GET.name())) {
|
||||
// if (!PatternMatchUtils.simpleMatch(permission.get(PermissionEnum.SUPER).toArray(new String[0]), request.getRequestURI()) ||
|
||||
// PatternMatchUtils.simpleMatch(permission.get(PermissionEnum.QUERY).toArray(new String[0]), request.getRequestURI())) {
|
||||
//
|
||||
// ResponseUtil.output(response, ResponseUtil.resultMap(false, 401, "抱歉,您没有访问权限"));
|
||||
// throw new NoPermissionException("权限不足");
|
||||
// }
|
||||
// } else {
|
||||
// if (!PatternMatchUtils.simpleMatch(permission.get(PermissionEnum.SUPER).toArray(new String[0]), request.getRequestURI())) {
|
||||
//
|
||||
// ResponseUtil.output(response, ResponseUtil.resultMap(false, 401, "抱歉,您没有访问权限"));
|
||||
// throw new NoPermissionException("权限不足");
|
||||
// }
|
||||
// }
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取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.MANAGER) + 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
package cn.lili.security;
|
||||
|
||||
import cn.lili.common.cache.Cache;
|
||||
import cn.lili.common.security.CustomAccessDeniedHandler;
|
||||
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 核心配置类 Manager安全配置中心
|
||||
*
|
||||
* @author Chopper
|
||||
* @date 2020/11/14 16:20
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class ManagerSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
|
||||
/**
|
||||
* 忽略验权配置
|
||||
*/
|
||||
private final IgnoredUrlsProperties ignoredUrlsProperties;
|
||||
|
||||
/**
|
||||
* spring security -》 权限不足处理
|
||||
*/
|
||||
private final CustomAccessDeniedHandler accessDeniedHandler;
|
||||
|
||||
|
||||
private final Cache<String> cache;
|
||||
|
||||
private final CorsConfigurationSource corsConfigurationSource;
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
|
||||
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http
|
||||
.authorizeRequests();
|
||||
// 配置的url 不需要授权
|
||||
for (String url : ignoredUrlsProperties.getUrls()) {
|
||||
log.error(url);
|
||||
registry.antMatchers(url).permitAll();
|
||||
}
|
||||
registry
|
||||
.and()
|
||||
// 禁止网页iframe
|
||||
.headers().frameOptions().disable()
|
||||
.and()
|
||||
.authorizeRequests()
|
||||
// 任何请求
|
||||
.anyRequest()
|
||||
// 需要身份认证
|
||||
.authenticated()
|
||||
.and()
|
||||
// 允许跨域
|
||||
.cors().configurationSource(corsConfigurationSource).and()
|
||||
// 关闭跨站请求防护
|
||||
.csrf().disable()
|
||||
// 前后端分离采用JWT 不需要session
|
||||
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
.and()
|
||||
// 自定义权限拒绝处理类
|
||||
.exceptionHandling().accessDeniedHandler(accessDeniedHandler)
|
||||
.and()
|
||||
// 添加JWT认证过滤器
|
||||
.addFilter(new ManagerAuthenticationFilter(authenticationManager(), cache));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user