From 393c9ec941dd925eee00fd96564ffe3a699cb6cb Mon Sep 17 00:00:00 2001 From: shahaibo <1023316923@qq.com> Date: Wed, 17 Jan 2024 10:33:37 +0800 Subject: [PATCH] =?UTF-8?q?TASK:=E8=AF=81=E4=B9=A6=E6=8E=A5=E6=94=B6?= =?UTF-8?q?=E6=B5=8B=E8=AF=95;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../security/config/SecurityConfig.java | 61 +++++++++++++------ .../da/controller/ThirdPartyController.java | 21 +++++++ 2 files changed, 62 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/ai/da/common/security/config/SecurityConfig.java b/src/main/java/com/ai/da/common/security/config/SecurityConfig.java index 773587c9..b0ebc161 100644 --- a/src/main/java/com/ai/da/common/security/config/SecurityConfig.java +++ b/src/main/java/com/ai/da/common/security/config/SecurityConfig.java @@ -3,6 +3,7 @@ package com.ai.da.common.security.config; import com.ai.da.common.security.*; import com.ai.da.common.security.filter.AuthenticationFilter; import com.ai.da.common.security.filter.UserAuthenticationProcessingFilter; +import com.ai.da.mapper.AccountMapper; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.security.authentication.AuthenticationManager; @@ -12,11 +13,14 @@ 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.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import javax.annotation.Resource; +import java.util.ArrayList; @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) @@ -45,6 +49,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { private AuthenticationFilter authenticationFilter; @Resource private UserPermissionEvaluator userPermissionEvaluator; + @Resource + private AccountMapper accountMapper; @Override @@ -53,26 +59,32 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { } @Override - protected void configure(HttpSecurity httpSecurity/*, WebSecurity web*/) throws Exception { -// web.ignoring().antMatchers("/test/**");//禁止所有过滤器 - httpSecurity.cors().disable()//禁用 CSRF - .authorizeRequests()//认证请求 - .antMatchers(securityProperties.getIgnorePaths()).permitAll()//忽略的请求 - .anyRequest().authenticated()//其余所有的请求都需要认证 - .and().headers().frameOptions().disable()// 防止iframe 造成跨域 - .and().exceptionHandling().authenticationEntryPoint(userAuthenticationEntryPointHandler)//未登录请求处理 - .accessDeniedHandler(userAuthAccessDeniedHandler)//无权限访问处理类 (此配置可以忽略,全局异常会先于Security框架处理异常,全局异常已特殊处理) - .and().formLogin().loginProcessingUrl(securityProperties.getAuthApi())//指定认证接口 - .successHandler(userLoginSuccessHandler)//登录成功处理器 - .failureHandler(userLoginFailureHandler)//登录失败处理器 - .and().cors().and().csrf().disable();//允许跨域 - //自定义过滤器在登录时认证用户名、密码 - httpSecurity.addFilterAt(userAuthenticationProcessingFilter, UsernamePasswordAuthenticationFilter.class) - .addFilterBefore(authenticationFilter, BasicAuthenticationFilter.class); - //不创建session会话 - httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); - //取消头缓存控制 - httpSecurity.headers().cacheControl(); + protected void configure(HttpSecurity httpSecurity) throws Exception { + httpSecurity.cors().disable() // 禁用 CSRF + .authorizeRequests() + .antMatchers(securityProperties.getIgnorePaths()).permitAll() + .antMatchers("/api/third/party/your-secured-endpoint").authenticated() // 需要验证的接口 + .anyRequest().permitAll() + .and() + .x509() + .subjectPrincipalRegex("CN=(.*?)(?:,|$)") + .userDetailsService(userDetailsService()) + .and() + .exceptionHandling() + .authenticationEntryPoint(userAuthenticationEntryPointHandler) + .accessDeniedHandler(userAuthAccessDeniedHandler) + .and() + .formLogin() + .loginProcessingUrl(securityProperties.getAuthApi()) + .successHandler(userLoginSuccessHandler) + .failureHandler(userLoginFailureHandler) + .and() + .addFilterAt(userAuthenticationProcessingFilter, UsernamePasswordAuthenticationFilter.class) + .addFilterBefore(authenticationFilter, BasicAuthenticationFilter.class) + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .and() + .headers().cacheControl() + ; } @Bean @@ -81,4 +93,13 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { handler.setPermissionEvaluator(userPermissionEvaluator); return handler; } + @Bean + public UserDetailsService userDetailsService() { +// return (UserDetailsService) accountMapper.selectById(88L); + return username -> { + // 这里可以根据用户名查找用户信息,例如从数据库中查询 + // 返回 UserDetails 对象 + return new User(username, "", new ArrayList<>()); + }; + } } diff --git a/src/main/java/com/ai/da/controller/ThirdPartyController.java b/src/main/java/com/ai/da/controller/ThirdPartyController.java index 72167882..13b17c73 100644 --- a/src/main/java/com/ai/da/controller/ThirdPartyController.java +++ b/src/main/java/com/ai/da/controller/ThirdPartyController.java @@ -7,11 +7,14 @@ import com.ai.da.service.AccountService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; +import java.security.cert.X509Certificate; @Api(tags = "Third Party Modules") @@ -62,4 +65,22 @@ public class ThirdPartyController { public Response existNoLoginRequired(@RequestBody NoLoginRequiredDTO noLoginRequiredDTO) { return Response.success(accountService.existNoLoginRequired(noLoginRequiredDTO)); } + + @GetMapping("/your-secured-endpoint") +// @PreAuthorize("hasRole('ROLE_USER')") + public String securedEndpoint(HttpServletRequest request, @AuthenticationPrincipal PreAuthenticatedAuthenticationToken authenticationToken) { + // 从请求属性中获取证书 + X509Certificate[] certificates = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate"); + if (certificates != null && certificates.length > 0) { + X509Certificate clientCertificate = certificates[0]; + // 可以从 clientCertificate 中获取证书信息,例如主题、颁发者等 + String subject = clientCertificate.getSubjectX500Principal().getName(); + String issuer = clientCertificate.getIssuerX500Principal().getName(); + // 处理逻辑 + return "Secured Endpoint. Client Subject: " + subject + ", Issuer: " + issuer; + } else { + // 证书不存在或获取失败 + return "Failed to retrieve client certificate."; + } + } }