From d9f709de3d53584bbd54565f3a40c2dd5c0b01ac Mon Sep 17 00:00:00 2001 From: guowei <3306787021@qq.com> Date: Thu, 5 Sep 2024 20:04:11 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=8E=A5=E5=8F=A3=E6=B5=8B?= =?UTF-8?q?=E8=AF=95token=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gw/test/config/OpenApiConfig.java | 23 +++++++++ .../gw/test/config/SecurityBeanConfig.java | 9 ++++ .../com/gw/test/config/SecurityConfig.java | 50 ++++++++++++++---- .../java/com/gw/test/config/WebConfig.java | 51 +++++++++++++++++++ .../gw/test/controller/GuoWeiController.java | 40 +++++++++------ .../test/filters/DynamicSecurityFilter.java | 1 + .../filters/JwtAuthenticationTokenFilter.java | 2 + src/main/resources/application.yml | 10 ++-- 8 files changed, 157 insertions(+), 29 deletions(-) create mode 100644 src/main/java/com/gw/test/config/OpenApiConfig.java create mode 100644 src/main/java/com/gw/test/config/WebConfig.java diff --git a/src/main/java/com/gw/test/config/OpenApiConfig.java b/src/main/java/com/gw/test/config/OpenApiConfig.java new file mode 100644 index 0000000..46e0505 --- /dev/null +++ b/src/main/java/com/gw/test/config/OpenApiConfig.java @@ -0,0 +1,23 @@ +package com.gw.test.config; + +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.info.License; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import org.springframework.http.HttpHeaders; + +@Configuration +public class OpenApiConfig { + @Bean + public OpenAPI api() { + return new OpenAPI().info(new Info().title("Test").version("v1.0.0").description( "接口测试")) + .addSecurityItem(new SecurityRequirement().addList(HttpHeaders.AUTHORIZATION)) + .components(new Components().addSecuritySchemes(HttpHeaders.AUTHORIZATION,new SecurityScheme() + .name(HttpHeaders.AUTHORIZATION).type(SecurityScheme.Type.HTTP).scheme("Bearer"))); + } +} diff --git a/src/main/java/com/gw/test/config/SecurityBeanConfig.java b/src/main/java/com/gw/test/config/SecurityBeanConfig.java index 18186ea..9d215bb 100644 --- a/src/main/java/com/gw/test/config/SecurityBeanConfig.java +++ b/src/main/java/com/gw/test/config/SecurityBeanConfig.java @@ -2,13 +2,17 @@ package com.gw.test.config; import com.gw.test.filters.*; import com.gw.test.utils.JWTUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; +@Slf4j @Configuration public class SecurityBeanConfig { @Bean @@ -23,6 +27,7 @@ public class SecurityBeanConfig { @Bean public JWTUtil jWTUtil() { + log.error("jwtUtil"); return new JWTUtil(); } @@ -43,19 +48,23 @@ public class SecurityBeanConfig { @ConditionalOnBean(name = "dynamicSecurityService") @Bean + @Autowired public DynamicAccessDecisionManager dynamicAccessDecisionManager() { return new DynamicAccessDecisionManager(); } @ConditionalOnBean(name = "dynamicSecurityService") @Bean + @Autowired public DynamicSecurityMetadataSource dynamicSecurityMetadataSource(DynamicSecurityService dynamicSecurityService) { return new DynamicSecurityMetadataSource(dynamicSecurityService); } @ConditionalOnBean(name = "dynamicSecurityService") @Bean + @Lazy(value = false) public DynamicSecurityFilter dynamicSecurityFilter(DynamicSecurityMetadataSource dynamicSecurityMetadataSource,IgnoreUrlsConfig ignoreUrlsConfig){ + log.error("动态权限注解支持启动"); return new DynamicSecurityFilter(dynamicSecurityMetadataSource,ignoreUrlsConfig); } } diff --git a/src/main/java/com/gw/test/config/SecurityConfig.java b/src/main/java/com/gw/test/config/SecurityConfig.java index 99d9c02..06ce361 100644 --- a/src/main/java/com/gw/test/config/SecurityConfig.java +++ b/src/main/java/com/gw/test/config/SecurityConfig.java @@ -18,6 +18,7 @@ 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.web.SecurityFilterChain; +import org.springframework.security.web.access.expression.WebExpressionAuthorizationManager; import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @@ -36,38 +37,67 @@ public class SecurityConfig { private final JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter; -// @Autowired(required = false) -// private DynamicSecurityService dynamicSecurityService; + @Autowired(required = false) + private DynamicSecurityService dynamicSecurityService; @Autowired(required = false) private DynamicSecurityFilter dynamicSecurityFilter; @Bean public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception{ - ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests(); +// ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests(); +// //不需要保护的资源路径允许访问 +// for (String url : ignoreUrlsConfig.getUrls()) { +// log.error("[{}] [{}]", "白名单路径", url); +// registry.requestMatchers(url).permitAll(); +// } +// //允许跨域请求的OPTIONS请求 +// registry.requestMatchers(HttpMethod.OPTIONS) +// .permitAll(); +// // 任何请求需要身份认证 +// registry.and() +// .authorizeRequests() +// .anyRequest() +// .authenticated() +// // 关闭跨站请求防护及不使用session +// .and() +// .csrf(AbstractHttpConfigurer::disable) +// .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) +// .exceptionHandling(exception -> exception +// .accessDeniedHandler(restfulAccessDeniedHandler) +// .authenticationEntryPoint(restAuthenticationEntryPoint)) +// // 自定义JWT认证过滤器 +// .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); +// // 添加动态权限校验过滤器 +//// .addFilterBefore(dynamicSecurityFilter, FilterSecurityInterceptor.class); +// return httpSecurity.build(); + + ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry registry = httpSecurity + .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .csrf(AbstractHttpConfigurer::disable) + .authorizeRequests(); //不需要保护的资源路径允许访问 for (String url : ignoreUrlsConfig.getUrls()) { -// log.error("[{}] [{}]", "白名单路径", url); + log.error("[{}] [{}]", "白名单路径", url); registry.requestMatchers(url).permitAll(); } //允许跨域请求的OPTIONS请求 registry.requestMatchers(HttpMethod.OPTIONS) .permitAll(); + // 任何请求需要身份认证 - registry.and() - .authorizeRequests() - .anyRequest() + registry.anyRequest() .authenticated() // 关闭跨站请求防护及不使用session .and() - .csrf(AbstractHttpConfigurer::disable) - .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .exceptionHandling(exception -> exception .accessDeniedHandler(restfulAccessDeniedHandler) .authenticationEntryPoint(restAuthenticationEntryPoint)) // 自定义JWT认证过滤器 .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); - // 添加动态权限校验过滤器 + // 添加动态权限校验过滤器 +// if (dynamicSecurityService != null) +// registry.and().addFilterBefore(dynamicSecurityFilter, FilterSecurityInterceptor.class); // .addFilterBefore(dynamicSecurityFilter, FilterSecurityInterceptor.class); return httpSecurity.build(); } diff --git a/src/main/java/com/gw/test/config/WebConfig.java b/src/main/java/com/gw/test/config/WebConfig.java new file mode 100644 index 0000000..ff6df64 --- /dev/null +++ b/src/main/java/com/gw/test/config/WebConfig.java @@ -0,0 +1,51 @@ +package com.gw.test.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + + +//@Configuration +public class WebConfig implements WebMvcConfigurer { + @Autowired +// LoginInterceptor loginInterceptor; + /** + * 跨域配置 + */ + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**")// + .allowedOriginPatterns("*")// + .allowedMethods("POST", "GET", "OPTIONS")// + .maxAge(3600)// + .allowCredentials(true);// + } + + + + @Override + public void addInterceptors(InterceptorRegistry registry) { + + // 对所有访问路径,都通过MyInterceptor类型的拦截器进行拦截 +// registry.addInterceptor(loginInterceptor)// +// .addPathPatterns("/**")// +// // 放行登陆接口 +// .excludePathPatterns("/**/login/**")// +// .excludePathPatterns("/**/ip/**") +// // swagger需要放行的资源 +// .excludePathPatterns("/favicon.ico")// +// .excludePathPatterns("/error")// +// .excludePathPatterns("/doc.html")// +// .excludePathPatterns("/webjars/**")// +// .excludePathPatterns("/swagger/**")// +// .excludePathPatterns("/v3/api-docs/**")// +// .excludePathPatterns("/swagger-resources/**")// +// .excludePathPatterns("/swagger-ui/**") +// .excludePathPatterns("/IpCheck/**")// +// ; + + } + +} diff --git a/src/main/java/com/gw/test/controller/GuoWeiController.java b/src/main/java/com/gw/test/controller/GuoWeiController.java index 97737c5..f08988d 100644 --- a/src/main/java/com/gw/test/controller/GuoWeiController.java +++ b/src/main/java/com/gw/test/controller/GuoWeiController.java @@ -6,12 +6,12 @@ import com.gw.test.domain.vo.LoginVo; import com.gw.test.entity.GuoWei; import com.gw.test.service.IGuoWeiService; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; - -import org.springframework.web.bind.annotation.RestController; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpHeaders; +import org.springframework.web.bind.annotation.*; import java.util.List; @@ -23,6 +23,7 @@ import java.util.List; * @author gw * @since 2024-09-04 */ +@Slf4j @RestController @RequiredArgsConstructor @RequestMapping("/guowei") @@ -31,31 +32,35 @@ public class GuoWeiController { private final IGuoWeiService service; - @Operation(summary = "用户列表",description = "用户列表接口") - @PostMapping("/list") + @SecurityRequirement(name = HttpHeaders.AUTHORIZATION) + @Operation(summary = "用户列表",description = "用户列表接口",security = { @SecurityRequirement(name = HttpHeaders.AUTHORIZATION) }) + @GetMapping("/list") public Result> list(){ return Result.ok(service.list()); } - @Operation(summary = "添加用户",description = "添加用户接口") - @PostMapping("/save") - public Result save(GuoWei guoWei) { - service.save(guoWei); - return Result.ok(); - } +// @SecurityRequirement(name = HttpHeaders.AUTHORIZATION) +// @Operation(summary = "添加用户",description = "添加用户接口") +// @PostMapping("/add") +// public Result save(@RequestBody GuoWei guoWei) { +// service.save(guoWei); +// return Result.ok(); +// } + @SecurityRequirement(name = HttpHeaders.AUTHORIZATION) @Operation(summary = "删除用户",description = "删除用户接口") - @PostMapping("/delete") - public Result delete(Integer id) { + @DeleteMapping("/delete") + public Result delete(@RequestParam("id") Integer id) { service.removeById(id); return Result.ok(); } + @SecurityRequirement(name = HttpHeaders.AUTHORIZATION) @Operation(summary = "用户修改",description = "用户列修改口") @PostMapping("/update") - public Result update(GuoWei guoWei) { + public Result update(@RequestBody GuoWei guoWei) { service.updateById(guoWei); return Result.ok(); } @@ -63,7 +68,10 @@ public class GuoWeiController { @Operation(summary = "用户登录",description = "用户登录接口") @PostMapping("/login") public Result login(String username, String password) { - return Result.ok(service.login(username, password)); + log.error("========>username:{},password:{}",username,password); + LoginVo login = service.login(username, password); + if (login != null) return Result.ok(login); + return Result.error("用户名或密码错误"); } @Operation(summary = "用户注册",description = "用户注册接口") diff --git a/src/main/java/com/gw/test/filters/DynamicSecurityFilter.java b/src/main/java/com/gw/test/filters/DynamicSecurityFilter.java index d72c623..ca5ad4c 100644 --- a/src/main/java/com/gw/test/filters/DynamicSecurityFilter.java +++ b/src/main/java/com/gw/test/filters/DynamicSecurityFilter.java @@ -43,6 +43,7 @@ public class DynamicSecurityFilter extends AbstractSecurityInterceptor implement @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + log.error("进入动态权限过滤器"); HttpServletRequest request = (HttpServletRequest) servletRequest; FilterInvocation fi = new FilterInvocation(servletRequest, servletResponse, filterChain); //OPTIONS请求直接放行 diff --git a/src/main/java/com/gw/test/filters/JwtAuthenticationTokenFilter.java b/src/main/java/com/gw/test/filters/JwtAuthenticationTokenFilter.java index e0ceab2..f9ea9a1 100644 --- a/src/main/java/com/gw/test/filters/JwtAuthenticationTokenFilter.java +++ b/src/main/java/com/gw/test/filters/JwtAuthenticationTokenFilter.java @@ -39,6 +39,8 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { +// log.error("================JWT过滤器执行================="); +// log.error(request.getRequestURI()); String authHeader = request.getHeader(this.tokenHeader); if (authHeader != null && authHeader.startsWith(this.tokenHead)) { String authToken = authHeader.substring(this.tokenHead.length());// The part after "Bearer " diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 766ee9a..cfb913c 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -47,10 +47,14 @@ secure: ignored: urls: - /webjars/** + - /favicon.ico + - /swagger/** - /swagger-resources/** - - /v3/** + - /docs/** + - /error + - /v3/api-docs/** + - /swagger-ui/** - /swagger-ui.html - - /docs - /doc.html - /guowei/login - - /guowei/register \ No newline at end of file + - /guowei/register