增加了用户缓存

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

Loading…
Cancel
Save