增加了用户缓存

master
GPU is all you need 4 years ago
parent 8782c05704
commit 7cc61baa2d
  1. 163
      awardBE/src/main/java/edu/ncst/award/config/SecurityConfig.java

@ -1,16 +1,19 @@
package edu.ncst.award.config;
import cn.hutool.extra.spring.SpringUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import edu.ncst.award.config.security.DataBaseUrlVoter;
import edu.ncst.award.config.security.CustomUserCache;
import edu.ncst.award.config.security.filter.AuthCheckFilter;
import edu.ncst.award.config.security.filter.LoginFilter;
import edu.ncst.award.exception.CodeMsg;
import edu.ncst.award.service.ILoginLogService;
import edu.ncst.award.service.impl.system.UserServiceImpl;
import edu.ncst.award.utils.ResultUtils;
import org.springframework.beans.factory.annotation.Autowired;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDecisionVoter;
@ -26,8 +29,7 @@ import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.core.userdetails.cache.SpringCacheBasedUserCache;
import org.springframework.security.web.access.expression.WebExpressionVoter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@ -39,25 +41,23 @@ import java.util.List;
* 安全配置
*/
@Configuration
@Slf4j
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled=true)
@RequiredArgsConstructor
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserServiceImpl userService;
@Autowired
private ILoginLogService loginLogService;
@Autowired
private DataBaseUrlVoter dataBaseUrlVoter;
@Autowired
private RedisTemplate<String, String> redisCacheTemplate;
private final UserServiceImpl userService;
private final ILoginLogService loginLogService;
private final DataBaseUrlVoter dataBaseUrlVoter;
private final RedisTemplate<String, String> redisCacheTemplate;
/**
* 认证失败处理类
*/
@Autowired
CustomAccessDeniedHandler accessDeniedHandler;
private final CustomAccessDeniedHandler accessDeniedHandler;
//org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)
/**
* 解决 无法直接注入 AuthenticationManager
*
@ -66,17 +66,18 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
*/
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception
{
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
/**
* 权限白名单
* 权限白名单'
* '
* <p>
* 注意该名单下匹配的 URL 不会经过鉴权因此也无法获取当前用户的信息
*/
private final String[] WHITE_LIST = {
"/v2/api-docs",
"/v3/api-docs",
"/configuration/ui",
"/swagger-resources/**",
"/configuration/**",
@ -95,20 +96,18 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
};
/**
* 权限投票访问决策管理器
*/
@Bean
public AccessDecisionManager accessDecisionManager() {
List<AccessDecisionVoter<? extends Object>> decisionVoters
List<AccessDecisionVoter<?>> decisionVoters
= Arrays.asList(
new WebExpressionVoter(),
new RoleVoter(),//主要用来判断当前请求是否具备该接口所需要的角色
dataBaseUrlVoter,
new AuthenticatedVoter());
return new UnanimousBased(decisionVoters);//要求所有 AccessDecisionVoter 均返回肯定的结果时,才代表授予权限。
return new UnanimousBased(decisionVoters);//要求所有 AccessDecisionVoter 一票否决,所有弃权时deny
}
@Override
@ -116,7 +115,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setHideUserNotFoundExceptions(false);
daoAuthenticationProvider.setUserDetailsService(userService);
daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
daoAuthenticationProvider.setUserCache(new CustomUserCache(redisCacheTemplate));
daoAuthenticationProvider.setPasswordEncoder(CustomDelegatingPasswordEncoder.createDelegatingPasswordEncoder());
auth.authenticationProvider(daoAuthenticationProvider);
}
@ -135,68 +135,73 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
* rememberMe | 允许通过remember-me登录的用户访问
* authenticated | 用户登录后可访问
*/
//权限验证 基于资源配置
// HttpSecurity 及WebSecurity 作用是不一样的:
// WebSecurity 主要针对的全局的忽略规则,
// HttpSecurity主要是权限控制规则。
// @Override
// protected void configure(HttpSecurity http) throws Exception {
//
// //允许跨域
// http.cors().and().anonymous().and()
// // CRSF禁用,因为不使用session
// .csrf().disable()
// .formLogin().disable().httpBasic().disable()
// .authorizeRequests()
// .accessDecisionManager(accessDecisionManager())//访问决策管理器
// .antMatchers("/api/login").permitAll()
// .antMatchers("/system/init").permitAll()
// // 除上面外的所有请求全部需要鉴权认证
// .anyRequest().authenticated()
// .and().exceptionHandling().accessDeniedHandler(accessDeniedHandler).and()
// .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
//
// http.addFilterAfter(new AuthCheckFilter(redisCacheTemplate), UsernamePasswordAuthenticationFilter.class)
// .addFilterAt(
// new LoginFilter(authenticationManager(), loginLogService, redisCacheTemplate), UsernamePasswordAuthenticationFilter.class
// )
// .exceptionHandling()//登录认证失败
// .authenticationEntryPoint(((request, response, authException) -> {
// response.setCharacterEncoding("utf-8");
// response.setContentType("application/json;charset=utf-8");
//
// PrintWriter out = response.getWriter();
// out.write(new ObjectMapper().writeValueAsString(ResultUtils.error(CodeMsg.USER_NEED_LOGIN)));
// out.flush();
// out.close();
// }));
//
// // 退出登录
// http.logout()
// .logoutUrl("/logout")
// .deleteCookies("JSESSIONID")
// .logoutSuccessHandler(((request, response, authentication) -> {
// PrintWriter out = response.getWriter();
// response.setContentType("application/json");
// out.write(new ObjectMapper().writeValueAsString(ResultUtils.success("注销成功")));
// out.flush();
// out.close();
// }));
// }
// 权限验证 基于资源配置
// HttpSecurity 及WebSecurity 作用是不一样的:
// WebSecurity 主要针对的全局的忽略规则,
// HttpSecurity主要是权限控制规则。
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception{
//调试阶段
httpSecurity.csrf().disable().authorizeRequests();
httpSecurity.authorizeRequests().anyRequest()
.permitAll().and().logout().permitAll();
protected void configure(HttpSecurity http) throws Exception {
//允许跨域
http.cors().and().anonymous().and()
// CSRF禁用,因为不使用session
.csrf().disable()
.formLogin().disable()
.httpBasic().disable()
.authorizeRequests()
.accessDecisionManager(accessDecisionManager())//访问决策管理器
.antMatchers("/api/login").permitAll()
.antMatchers("/system/init").permitAll()
// 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated()
.and().exceptionHandling().accessDeniedHandler(accessDeniedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterAfter(new AuthCheckFilter(redisCacheTemplate), UsernamePasswordAuthenticationFilter.class)
.addFilterAt(new LoginFilter(authenticationManager(), loginLogService, redisCacheTemplate), UsernamePasswordAuthenticationFilter.class)
.exceptionHandling()//登录认证失败
.authenticationEntryPoint(((request, response, authException) -> {
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
PrintWriter out = response.getWriter();
out.write(new ObjectMapper().writeValueAsString(ResultUtils.error(CodeMsg.USER_NEED_LOGIN)));
out.flush();
out.close();
}));
// 退出登录
http.logout()
.logoutUrl("/logout")
.deleteCookies("JSESSIONID")
.logoutSuccessHandler(((request, response, authentication) -> {
PrintWriter out = response.getWriter();
response.setContentType("application/json");
out.write(new ObjectMapper().writeValueAsString(ResultUtils.success("注销成功")));
out.flush();
out.close();
}));
}
// @Override
// protected void configure(HttpSecurity httpSecurity) throws Exception{
// //调试阶段
// httpSecurity.csrf().disable().authorizeRequests();
// httpSecurity.authorizeRequests().anyRequest()
// .permitAll().and().logout().permitAll();
// }
//用于配置全局的某些通用事物,例如静态资源等
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(WHITE_LIST);
}
// @Bean
// public PasswordEncoder delegatingPasswordEncoder(){
// return CustomDelegatingPasswordEncoder.createDelegatingPasswordEncoder();
// }
}

Loading…
Cancel
Save