|
|
@ -2,16 +2,17 @@ package com.ruoyi.framework.config; |
|
|
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.context.annotation.Bean; |
|
|
|
import org.springframework.context.annotation.Configuration; |
|
|
|
import org.springframework.http.HttpMethod; |
|
|
|
import org.springframework.security.authentication.AuthenticationManager; |
|
|
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; |
|
|
|
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; |
|
|
|
import org.springframework.security.authentication.ProviderManager; |
|
|
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider; |
|
|
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; |
|
|
|
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.security.core.userdetails.UserDetailsService; |
|
|
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |
|
|
|
import org.springframework.security.web.SecurityFilterChain; |
|
|
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; |
|
|
|
import org.springframework.security.web.authentication.logout.LogoutFilter; |
|
|
|
import org.springframework.web.filter.CorsFilter; |
|
|
@ -25,8 +26,9 @@ import com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl; |
|
|
|
* |
|
|
|
* @author ruoyi |
|
|
|
*/ |
|
|
|
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) |
|
|
|
public class SecurityConfig extends WebSecurityConfigurerAdapter |
|
|
|
@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true) |
|
|
|
@Configuration |
|
|
|
public class SecurityConfig |
|
|
|
{ |
|
|
|
/** |
|
|
|
* 自定义用户认证逻辑 |
|
|
@ -65,16 +67,15 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter |
|
|
|
private PermitAllUrlProperties permitAllUrl; |
|
|
|
|
|
|
|
/** |
|
|
|
* 解决 无法直接注入 AuthenticationManager |
|
|
|
* |
|
|
|
* @return |
|
|
|
* @throws Exception |
|
|
|
* 身份验证实现 |
|
|
|
*/ |
|
|
|
@Bean |
|
|
|
@Override |
|
|
|
public AuthenticationManager authenticationManagerBean() throws Exception |
|
|
|
public AuthenticationManager authenticationManager() |
|
|
|
{ |
|
|
|
return super.authenticationManagerBean(); |
|
|
|
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider(); |
|
|
|
daoAuthenticationProvider.setUserDetailsService(userDetailsService); |
|
|
|
daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder()); |
|
|
|
return new ProviderManager(daoAuthenticationProvider); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@ -92,40 +93,39 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter |
|
|
|
* rememberMe | 允许通过remember-me登录的用户访问 |
|
|
|
* authenticated | 用户登录后可访问 |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
protected void configure(HttpSecurity httpSecurity) throws Exception |
|
|
|
@Bean |
|
|
|
protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception |
|
|
|
{ |
|
|
|
// 注解标记允许匿名访问的url
|
|
|
|
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests(); |
|
|
|
permitAllUrl.getUrls().forEach(url -> registry.antMatchers(url).permitAll()); |
|
|
|
|
|
|
|
httpSecurity |
|
|
|
return httpSecurity |
|
|
|
// CSRF禁用,因为不使用session
|
|
|
|
.csrf().disable() |
|
|
|
.csrf(csrf -> csrf.disable()) |
|
|
|
// 禁用HTTP响应标头
|
|
|
|
.headers().cacheControl().disable().and() |
|
|
|
.headers((headersCustomizer) -> { |
|
|
|
headersCustomizer.cacheControl(cache -> cache.disable()).frameOptions(options -> options.sameOrigin()); |
|
|
|
}) |
|
|
|
// 认证失败处理类
|
|
|
|
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() |
|
|
|
.exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler)) |
|
|
|
// 基于token,所以不需要session
|
|
|
|
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() |
|
|
|
// 过滤请求
|
|
|
|
.authorizeRequests() |
|
|
|
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) |
|
|
|
// 注解标记允许匿名访问的url
|
|
|
|
.authorizeHttpRequests((requests) -> { |
|
|
|
permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll()); |
|
|
|
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
|
|
|
|
.antMatchers("/login", "/register", "/captchaImage").permitAll() |
|
|
|
requests.antMatchers("/login", "/register", "/captchaImage").permitAll() |
|
|
|
// 静态资源,可匿名访问
|
|
|
|
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() |
|
|
|
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() |
|
|
|
// 除上面外的所有请求全部需要鉴权认证
|
|
|
|
.anyRequest().authenticated() |
|
|
|
.and() |
|
|
|
.headers().frameOptions().disable(); |
|
|
|
.anyRequest().authenticated(); |
|
|
|
}) |
|
|
|
// 添加Logout filter
|
|
|
|
httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler); |
|
|
|
.logout(logout -> logout.logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler)) |
|
|
|
// 添加JWT filter
|
|
|
|
httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); |
|
|
|
.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class) |
|
|
|
// 添加CORS filter
|
|
|
|
httpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class); |
|
|
|
httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class); |
|
|
|
.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class) |
|
|
|
.addFilterBefore(corsFilter, LogoutFilter.class) |
|
|
|
.build(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@ -136,13 +136,4 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter |
|
|
|
{ |
|
|
|
return new BCryptPasswordEncoder(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 身份认证接口 |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
protected void configure(AuthenticationManagerBuilder auth) throws Exception |
|
|
|
{ |
|
|
|
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder()); |
|
|
|
} |
|
|
|
} |
|
|
|