Commit d9c2da7c919508c52fd2826b90758d0372bacc54
1 parent
15ee097a
1. 【新增】接口支持通过 `@PermitAll` 注解,允许匿名(未登录)进行访问
2. 【新增】`yudao.security.permit-all-urls` 配置项,允许匿名(未登录)进行访问
Showing
17 changed files
with
102 additions
and
86 deletions
yudao-framework/yudao-spring-boot-starter-security/pom.xml
| @@ -44,6 +44,12 @@ | @@ -44,6 +44,12 @@ | ||
| 44 | <artifactId>spring-boot-starter-security</artifactId> | 44 | <artifactId>spring-boot-starter-security</artifactId> |
| 45 | </dependency> | 45 | </dependency> |
| 46 | 46 | ||
| 47 | + <!-- 工具类相关 --> | ||
| 48 | + <dependency> | ||
| 49 | + <groupId>com.google.guava</groupId> | ||
| 50 | + <artifactId>guava</artifactId> | ||
| 51 | + </dependency> | ||
| 52 | + | ||
| 47 | <!-- 业务组件 --> | 53 | <!-- 业务组件 --> |
| 48 | <dependency> | 54 | <dependency> |
| 49 | <groupId>cn.iocoder.boot</groupId> | 55 | <groupId>cn.iocoder.boot</groupId> |
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/SecurityProperties.java
| @@ -6,6 +6,8 @@ import org.springframework.validation.annotation.Validated; | @@ -6,6 +6,8 @@ import org.springframework.validation.annotation.Validated; | ||
| 6 | 6 | ||
| 7 | import javax.validation.constraints.NotEmpty; | 7 | import javax.validation.constraints.NotEmpty; |
| 8 | import javax.validation.constraints.NotNull; | 8 | import javax.validation.constraints.NotNull; |
| 9 | +import java.util.Collections; | ||
| 10 | +import java.util.List; | ||
| 9 | 11 | ||
| 10 | @ConfigurationProperties(prefix = "yudao.security") | 12 | @ConfigurationProperties(prefix = "yudao.security") |
| 11 | @Validated | 13 | @Validated |
| @@ -30,4 +32,9 @@ public class SecurityProperties { | @@ -30,4 +32,9 @@ public class SecurityProperties { | ||
| 30 | @NotEmpty(message = "mock 模式的密钥不能为空") // 这里设置了一个默认值,因为实际上只有 mockEnable 为 true 时才需要配置。 | 32 | @NotEmpty(message = "mock 模式的密钥不能为空") // 这里设置了一个默认值,因为实际上只有 mockEnable 为 true 时才需要配置。 |
| 31 | private String mockSecret = "test"; | 33 | private String mockSecret = "test"; |
| 32 | 34 | ||
| 35 | + /** | ||
| 36 | + * 免登录的 URL 列表 | ||
| 37 | + */ | ||
| 38 | + private List<String> permitAllUrls = Collections.emptyList(); | ||
| 39 | + | ||
| 33 | } | 40 | } |
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoWebSecurityConfigurerAdapter.java
| @@ -2,7 +2,10 @@ package cn.iocoder.yudao.framework.security.config; | @@ -2,7 +2,10 @@ package cn.iocoder.yudao.framework.security.config; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.security.core.filter.TokenAuthenticationFilter; | 3 | import cn.iocoder.yudao.framework.security.core.filter.TokenAuthenticationFilter; |
| 4 | import cn.iocoder.yudao.framework.web.config.WebProperties; | 4 | import cn.iocoder.yudao.framework.web.config.WebProperties; |
| 5 | +import com.google.common.collect.HashMultimap; | ||
| 6 | +import com.google.common.collect.Multimap; | ||
| 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
| 8 | +import org.springframework.context.ApplicationContext; | ||
| 6 | import org.springframework.context.annotation.Bean; | 9 | import org.springframework.context.annotation.Bean; |
| 7 | import org.springframework.context.annotation.Configuration; | 10 | import org.springframework.context.annotation.Configuration; |
| 8 | import org.springframework.http.HttpMethod; | 11 | import org.springframework.http.HttpMethod; |
| @@ -14,9 +17,15 @@ import org.springframework.security.config.http.SessionCreationPolicy; | @@ -14,9 +17,15 @@ import org.springframework.security.config.http.SessionCreationPolicy; | ||
| 14 | import org.springframework.security.web.AuthenticationEntryPoint; | 17 | import org.springframework.security.web.AuthenticationEntryPoint; |
| 15 | import org.springframework.security.web.access.AccessDeniedHandler; | 18 | import org.springframework.security.web.access.AccessDeniedHandler; |
| 16 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | 19 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; |
| 20 | +import org.springframework.web.method.HandlerMethod; | ||
| 21 | +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; | ||
| 22 | +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; | ||
| 17 | 23 | ||
| 18 | import javax.annotation.Resource; | 24 | import javax.annotation.Resource; |
| 25 | +import javax.annotation.security.PermitAll; | ||
| 19 | import java.util.List; | 26 | import java.util.List; |
| 27 | +import java.util.Map; | ||
| 28 | +import java.util.Set; | ||
| 20 | 29 | ||
| 21 | /** | 30 | /** |
| 22 | * 自定义的 Spring Security 配置适配器实现 | 31 | * 自定义的 Spring Security 配置适配器实现 |
| @@ -29,6 +38,8 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap | @@ -29,6 +38,8 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap | ||
| 29 | 38 | ||
| 30 | @Resource | 39 | @Resource |
| 31 | private WebProperties webProperties; | 40 | private WebProperties webProperties; |
| 41 | + @Resource | ||
| 42 | + private SecurityProperties securityProperties; | ||
| 32 | 43 | ||
| 33 | /** | 44 | /** |
| 34 | * 认证失败处理类 Bean | 45 | * 认证失败处理类 Bean |
| @@ -54,6 +65,9 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap | @@ -54,6 +65,9 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap | ||
| 54 | @Resource | 65 | @Resource |
| 55 | private List<AuthorizeRequestsCustomizer> authorizeRequestsCustomizers; | 66 | private List<AuthorizeRequestsCustomizer> authorizeRequestsCustomizers; |
| 56 | 67 | ||
| 68 | + @Resource | ||
| 69 | + private ApplicationContext applicationContext; | ||
| 70 | + | ||
| 57 | /** | 71 | /** |
| 58 | * 由于 Spring Security 创建 AuthenticationManager 对象时,没声明 @Bean 注解,导致无法被注入 | 72 | * 由于 Spring Security 创建 AuthenticationManager 对象时,没声明 @Bean 注解,导致无法被注入 |
| 59 | * 通过覆写父类的该方法,添加 @Bean 注解,解决该问题 | 73 | * 通过覆写父类的该方法,添加 @Bean 注解,解决该问题 |
| @@ -98,13 +112,21 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap | @@ -98,13 +112,21 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap | ||
| 98 | .accessDeniedHandler(accessDeniedHandler); | 112 | .accessDeniedHandler(accessDeniedHandler); |
| 99 | // 登录、登录暂时不使用 Spring Security 的拓展点,主要考虑一方面拓展多用户、多种登录方式相对复杂,一方面用户的学习成本较高 | 113 | // 登录、登录暂时不使用 Spring Security 的拓展点,主要考虑一方面拓展多用户、多种登录方式相对复杂,一方面用户的学习成本较高 |
| 100 | 114 | ||
| 115 | + // 获得 @PermitAll 带来的 URL 列表,免登录 | ||
| 116 | + Multimap<HttpMethod, String> permitAllUrls = getPermitAllUrlsFromAnnotations(); | ||
| 101 | // 设置每个请求的权限 | 117 | // 设置每个请求的权限 |
| 102 | httpSecurity | 118 | httpSecurity |
| 103 | // ①:全局共享规则 | 119 | // ①:全局共享规则 |
| 104 | .authorizeRequests() | 120 | .authorizeRequests() |
| 105 | // 静态资源,可匿名访问 | 121 | // 静态资源,可匿名访问 |
| 106 | .antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll() | 122 | .antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", "/**/*.js").permitAll() |
| 107 | - .antMatchers(HttpMethod.GET, "/admin-ui/**").permitAll() | 123 | + // 设置 @PermitAll 无需认证 |
| 124 | + .antMatchers(HttpMethod.GET, permitAllUrls.get(HttpMethod.GET).toArray(new String[0])).permitAll() | ||
| 125 | + .antMatchers(HttpMethod.POST, permitAllUrls.get(HttpMethod.POST).toArray(new String[0])).permitAll() | ||
| 126 | + .antMatchers(HttpMethod.PUT, permitAllUrls.get(HttpMethod.PUT).toArray(new String[0])).permitAll() | ||
| 127 | + .antMatchers(HttpMethod.DELETE, permitAllUrls.get(HttpMethod.DELETE).toArray(new String[0])).permitAll() | ||
| 128 | + // 基于 yudao.security.permit-all-urls 无需认证 | ||
| 129 | + .antMatchers(securityProperties.getPermitAllUrls().toArray(new String[0])).permitAll() | ||
| 108 | // 设置 App API 无需认证 | 130 | // 设置 App API 无需认证 |
| 109 | .antMatchers(buildAppApi("/**")).permitAll() | 131 | .antMatchers(buildAppApi("/**")).permitAll() |
| 110 | // ②:每个项目的自定义规则 | 132 | // ②:每个项目的自定义规则 |
| @@ -118,9 +140,46 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap | @@ -118,9 +140,46 @@ public class YudaoWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdap | ||
| 118 | // 添加 JWT Filter | 140 | // 添加 JWT Filter |
| 119 | httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); | 141 | httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); |
| 120 | } | 142 | } |
| 121 | - | 143 | + |
| 122 | private String buildAppApi(String url) { | 144 | private String buildAppApi(String url) { |
| 123 | return webProperties.getAppApi().getPrefix() + url; | 145 | return webProperties.getAppApi().getPrefix() + url; |
| 124 | } | 146 | } |
| 125 | 147 | ||
| 148 | + private Multimap<HttpMethod, String> getPermitAllUrlsFromAnnotations() { | ||
| 149 | + Multimap<HttpMethod, String> result = HashMultimap.create(); | ||
| 150 | + // 获得接口对应的 HandlerMethod 集合 | ||
| 151 | + RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) | ||
| 152 | + applicationContext.getBean("requestMappingHandlerMapping"); | ||
| 153 | + Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods(); | ||
| 154 | + // 获得有 @PermitAll 注解的接口 | ||
| 155 | + for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethodMap.entrySet()) { | ||
| 156 | + HandlerMethod handlerMethod = entry.getValue(); | ||
| 157 | + if (!handlerMethod.hasMethodAnnotation(PermitAll.class)) { | ||
| 158 | + continue; | ||
| 159 | + } | ||
| 160 | + if (entry.getKey().getPatternsCondition() == null) { | ||
| 161 | + continue; | ||
| 162 | + } | ||
| 163 | + Set<String> urls = entry.getKey().getPatternsCondition().getPatterns(); | ||
| 164 | + // 根据请求方法,添加到 result 结果 | ||
| 165 | + entry.getKey().getMethodsCondition().getMethods().forEach(requestMethod -> { | ||
| 166 | + switch (requestMethod) { | ||
| 167 | + case GET: | ||
| 168 | + result.putAll(HttpMethod.GET, urls); | ||
| 169 | + break; | ||
| 170 | + case POST: | ||
| 171 | + result.putAll(HttpMethod.POST, urls); | ||
| 172 | + break; | ||
| 173 | + case PUT: | ||
| 174 | + result.putAll(HttpMethod.PUT, urls); | ||
| 175 | + break; | ||
| 176 | + case DELETE: | ||
| 177 | + result.putAll(HttpMethod.DELETE, urls); | ||
| 178 | + break; | ||
| 179 | + } | ||
| 180 | + }); | ||
| 181 | + } | ||
| 182 | + return result; | ||
| 183 | + } | ||
| 184 | + | ||
| 126 | } | 185 | } |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java
| @@ -22,6 +22,7 @@ import org.springframework.web.bind.annotation.*; | @@ -22,6 +22,7 @@ import org.springframework.web.bind.annotation.*; | ||
| 22 | import org.springframework.web.multipart.MultipartFile; | 22 | import org.springframework.web.multipart.MultipartFile; |
| 23 | 23 | ||
| 24 | import javax.annotation.Resource; | 24 | import javax.annotation.Resource; |
| 25 | +import javax.annotation.security.PermitAll; | ||
| 25 | import javax.servlet.http.HttpServletResponse; | 26 | import javax.servlet.http.HttpServletResponse; |
| 26 | import javax.validation.Valid; | 27 | import javax.validation.Valid; |
| 27 | 28 | ||
| @@ -59,6 +60,7 @@ public class FileController { | @@ -59,6 +60,7 @@ public class FileController { | ||
| 59 | } | 60 | } |
| 60 | 61 | ||
| 61 | @GetMapping("/{configId}/get/{path}") | 62 | @GetMapping("/{configId}/get/{path}") |
| 63 | + @PermitAll | ||
| 62 | @ApiOperation("下载文件") | 64 | @ApiOperation("下载文件") |
| 63 | @ApiImplicitParams({ | 65 | @ApiImplicitParams({ |
| 64 | @ApiImplicitParam(name = "configId", value = "配置编号", required = true, dataTypeClass = Long.class), | 66 | @ApiImplicitParam(name = "configId", value = "配置编号", required = true, dataTypeClass = Long.class), |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/security/config/SecurityConfiguration.java
| @@ -35,8 +35,6 @@ public class SecurityConfiguration { | @@ -35,8 +35,6 @@ public class SecurityConfiguration { | ||
| 35 | // Spring Boot Admin Server 的安全配置 | 35 | // Spring Boot Admin Server 的安全配置 |
| 36 | registry.antMatchers(adminSeverContextPath).anonymous() | 36 | registry.antMatchers(adminSeverContextPath).anonymous() |
| 37 | .antMatchers(adminSeverContextPath + "/**").anonymous(); | 37 | .antMatchers(adminSeverContextPath + "/**").anonymous(); |
| 38 | - // 文件的获取接口,可匿名访问 | ||
| 39 | - registry.antMatchers(buildAdminApi("/infra/file/*/get/**"), buildAppApi("/infra/file/get/**")).permitAll(); | ||
| 40 | } | 38 | } |
| 41 | 39 | ||
| 42 | }; | 40 | }; |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java
| @@ -17,6 +17,7 @@ import org.springframework.validation.annotation.Validated; | @@ -17,6 +17,7 @@ import org.springframework.validation.annotation.Validated; | ||
| 17 | import org.springframework.web.bind.annotation.*; | 17 | import org.springframework.web.bind.annotation.*; |
| 18 | 18 | ||
| 19 | import javax.annotation.Resource; | 19 | import javax.annotation.Resource; |
| 20 | +import javax.annotation.security.PermitAll; | ||
| 20 | import javax.servlet.http.HttpServletRequest; | 21 | import javax.servlet.http.HttpServletRequest; |
| 21 | import javax.validation.Valid; | 22 | import javax.validation.Valid; |
| 22 | 23 | ||
| @@ -43,6 +44,7 @@ public class AppAuthController { | @@ -43,6 +44,7 @@ public class AppAuthController { | ||
| 43 | } | 44 | } |
| 44 | 45 | ||
| 45 | @PostMapping("/logout") | 46 | @PostMapping("/logout") |
| 47 | + @PermitAll | ||
| 46 | @ApiOperation("登出系统") | 48 | @ApiOperation("登出系统") |
| 47 | public CommonResult<Boolean> logout(HttpServletRequest request) { | 49 | public CommonResult<Boolean> logout(HttpServletRequest request) { |
| 48 | String token = SecurityFrameworkUtils.obtainAuthorization(request, securityProperties.getTokenHeader()); | 50 | String token = SecurityFrameworkUtils.obtainAuthorization(request, securityProperties.getTokenHeader()); |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/package-info.java
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/security/config/SecurityConfiguration.java deleted
| 1 | -package cn.iocoder.yudao.module.member.framework.security.config; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer; | ||
| 4 | -import org.springframework.context.annotation.Bean; | ||
| 5 | -import org.springframework.context.annotation.Configuration; | ||
| 6 | -import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
| 7 | -import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; | ||
| 8 | - | ||
| 9 | -/** | ||
| 10 | - * Member 模块的 Security 配置 | ||
| 11 | - */ | ||
| 12 | -@Configuration("memberSecurityConfiguration") | ||
| 13 | -public class SecurityConfiguration { | ||
| 14 | - | ||
| 15 | - @Bean("memberAuthorizeRequestsCustomizer") | ||
| 16 | - public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() { | ||
| 17 | - return new AuthorizeRequestsCustomizer() { | ||
| 18 | - | ||
| 19 | - @Override | ||
| 20 | - public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) { | ||
| 21 | - // 登录的接口 | ||
| 22 | - registry.antMatchers(buildAdminApi("/member/auth/logout")).permitAll(); | ||
| 23 | - } | ||
| 24 | - | ||
| 25 | - }; | ||
| 26 | - } | ||
| 27 | - | ||
| 28 | -} |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/security/core/package-info.java deleted
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java
| @@ -27,6 +27,7 @@ import org.springframework.validation.annotation.Validated; | @@ -27,6 +27,7 @@ import org.springframework.validation.annotation.Validated; | ||
| 27 | import org.springframework.web.bind.annotation.*; | 27 | import org.springframework.web.bind.annotation.*; |
| 28 | 28 | ||
| 29 | import javax.annotation.Resource; | 29 | import javax.annotation.Resource; |
| 30 | +import javax.annotation.security.PermitAll; | ||
| 30 | import javax.servlet.http.HttpServletRequest; | 31 | import javax.servlet.http.HttpServletRequest; |
| 31 | import javax.validation.Valid; | 32 | import javax.validation.Valid; |
| 32 | import java.util.List; | 33 | import java.util.List; |
| @@ -59,6 +60,7 @@ public class AuthController { | @@ -59,6 +60,7 @@ public class AuthController { | ||
| 59 | private SecurityProperties securityProperties; | 60 | private SecurityProperties securityProperties; |
| 60 | 61 | ||
| 61 | @PostMapping("/login") | 62 | @PostMapping("/login") |
| 63 | + @PermitAll | ||
| 62 | @ApiOperation("使用账号密码登录") | 64 | @ApiOperation("使用账号密码登录") |
| 63 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 | 65 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 |
| 64 | public CommonResult<AuthLoginRespVO> login(@RequestBody @Valid AuthLoginReqVO reqVO) { | 66 | public CommonResult<AuthLoginRespVO> login(@RequestBody @Valid AuthLoginReqVO reqVO) { |
| @@ -66,6 +68,7 @@ public class AuthController { | @@ -66,6 +68,7 @@ public class AuthController { | ||
| 66 | } | 68 | } |
| 67 | 69 | ||
| 68 | @PostMapping("/logout") | 70 | @PostMapping("/logout") |
| 71 | + @PermitAll | ||
| 69 | @ApiOperation("登出系统") | 72 | @ApiOperation("登出系统") |
| 70 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 | 73 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 |
| 71 | public CommonResult<Boolean> logout(HttpServletRequest request) { | 74 | public CommonResult<Boolean> logout(HttpServletRequest request) { |
| @@ -77,6 +80,7 @@ public class AuthController { | @@ -77,6 +80,7 @@ public class AuthController { | ||
| 77 | } | 80 | } |
| 78 | 81 | ||
| 79 | @PostMapping("/refresh-token") | 82 | @PostMapping("/refresh-token") |
| 83 | + @PermitAll | ||
| 80 | @ApiOperation("刷新令牌") | 84 | @ApiOperation("刷新令牌") |
| 81 | @ApiImplicitParam(name = "refreshToken", value = "刷新令牌", required = true, dataTypeClass = String.class) | 85 | @ApiImplicitParam(name = "refreshToken", value = "刷新令牌", required = true, dataTypeClass = String.class) |
| 82 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 | 86 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 |
| @@ -119,6 +123,7 @@ public class AuthController { | @@ -119,6 +123,7 @@ public class AuthController { | ||
| 119 | // ========== 短信登录相关 ========== | 123 | // ========== 短信登录相关 ========== |
| 120 | 124 | ||
| 121 | @PostMapping("/sms-login") | 125 | @PostMapping("/sms-login") |
| 126 | + @PermitAll | ||
| 122 | @ApiOperation("使用短信验证码登录") | 127 | @ApiOperation("使用短信验证码登录") |
| 123 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 | 128 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 |
| 124 | public CommonResult<AuthLoginRespVO> smsLogin(@RequestBody @Valid AuthSmsLoginReqVO reqVO) { | 129 | public CommonResult<AuthLoginRespVO> smsLogin(@RequestBody @Valid AuthSmsLoginReqVO reqVO) { |
| @@ -126,6 +131,7 @@ public class AuthController { | @@ -126,6 +131,7 @@ public class AuthController { | ||
| 126 | } | 131 | } |
| 127 | 132 | ||
| 128 | @PostMapping("/send-sms-code") | 133 | @PostMapping("/send-sms-code") |
| 134 | + @PermitAll | ||
| 129 | @ApiOperation(value = "发送手机验证码") | 135 | @ApiOperation(value = "发送手机验证码") |
| 130 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 | 136 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 |
| 131 | public CommonResult<Boolean> sendLoginSmsCode(@RequestBody @Valid AuthSmsSendReqVO reqVO) { | 137 | public CommonResult<Boolean> sendLoginSmsCode(@RequestBody @Valid AuthSmsSendReqVO reqVO) { |
| @@ -136,6 +142,7 @@ public class AuthController { | @@ -136,6 +142,7 @@ public class AuthController { | ||
| 136 | // ========== 社交登录相关 ========== | 142 | // ========== 社交登录相关 ========== |
| 137 | 143 | ||
| 138 | @GetMapping("/social-auth-redirect") | 144 | @GetMapping("/social-auth-redirect") |
| 145 | + @PermitAll | ||
| 139 | @ApiOperation("社交授权的跳转") | 146 | @ApiOperation("社交授权的跳转") |
| 140 | @ApiImplicitParams({ | 147 | @ApiImplicitParams({ |
| 141 | @ApiImplicitParam(name = "type", value = "社交类型", required = true, dataTypeClass = Integer.class), | 148 | @ApiImplicitParam(name = "type", value = "社交类型", required = true, dataTypeClass = Integer.class), |
| @@ -147,6 +154,7 @@ public class AuthController { | @@ -147,6 +154,7 @@ public class AuthController { | ||
| 147 | } | 154 | } |
| 148 | 155 | ||
| 149 | @PostMapping("/social-login") | 156 | @PostMapping("/social-login") |
| 157 | + @PermitAll | ||
| 150 | @ApiOperation(value = "社交快捷登录,使用 code 授权码", notes = "适合未登录的用户,但是社交账号已绑定用户") | 158 | @ApiOperation(value = "社交快捷登录,使用 code 授权码", notes = "适合未登录的用户,但是社交账号已绑定用户") |
| 151 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 | 159 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 |
| 152 | public CommonResult<AuthLoginRespVO> socialQuickLogin(@RequestBody @Valid AuthSocialLoginReqVO reqVO) { | 160 | public CommonResult<AuthLoginRespVO> socialQuickLogin(@RequestBody @Valid AuthSocialLoginReqVO reqVO) { |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/common/CaptchaController.java
| @@ -10,6 +10,7 @@ import org.springframework.web.bind.annotation.RequestMapping; | @@ -10,6 +10,7 @@ import org.springframework.web.bind.annotation.RequestMapping; | ||
| 10 | import org.springframework.web.bind.annotation.RestController; | 10 | import org.springframework.web.bind.annotation.RestController; |
| 11 | 11 | ||
| 12 | import javax.annotation.Resource; | 12 | import javax.annotation.Resource; |
| 13 | +import javax.annotation.security.PermitAll; | ||
| 13 | 14 | ||
| 14 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 15 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 15 | 16 | ||
| @@ -22,6 +23,7 @@ public class CaptchaController { | @@ -22,6 +23,7 @@ public class CaptchaController { | ||
| 22 | private CaptchaService captchaService; | 23 | private CaptchaService captchaService; |
| 23 | 24 | ||
| 24 | @GetMapping("/get-image") | 25 | @GetMapping("/get-image") |
| 26 | + @PermitAll | ||
| 25 | @ApiOperation("生成图片验证码") | 27 | @ApiOperation("生成图片验证码") |
| 26 | public CommonResult<CaptchaImageRespVO> getCaptchaImage() { | 28 | public CommonResult<CaptchaImageRespVO> getCaptchaImage() { |
| 27 | return success(captchaService.getCaptchaImage()); | 29 | return success(captchaService.getCaptchaImage()); |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/oauth2/OAuth2OpenController.java
| @@ -31,6 +31,7 @@ import org.springframework.validation.annotation.Validated; | @@ -31,6 +31,7 @@ import org.springframework.validation.annotation.Validated; | ||
| 31 | import org.springframework.web.bind.annotation.*; | 31 | import org.springframework.web.bind.annotation.*; |
| 32 | 32 | ||
| 33 | import javax.annotation.Resource; | 33 | import javax.annotation.Resource; |
| 34 | +import javax.annotation.security.PermitAll; | ||
| 34 | import javax.servlet.http.HttpServletRequest; | 35 | import javax.servlet.http.HttpServletRequest; |
| 35 | import java.util.Collections; | 36 | import java.util.Collections; |
| 36 | import java.util.List; | 37 | import java.util.List; |
| @@ -82,6 +83,7 @@ public class OAuth2OpenController { | @@ -82,6 +83,7 @@ public class OAuth2OpenController { | ||
| 82 | * 注意,默认需要传递 client_id + client_secret 参数 | 83 | * 注意,默认需要传递 client_id + client_secret 参数 |
| 83 | */ | 84 | */ |
| 84 | @PostMapping("/token") | 85 | @PostMapping("/token") |
| 86 | + @PermitAll | ||
| 85 | @ApiOperation(value = "获得访问令牌", notes = "适合 code 授权码模式,或者 implicit 简化模式;在 sso.vue 单点登录界面被【获取】调用") | 87 | @ApiOperation(value = "获得访问令牌", notes = "适合 code 授权码模式,或者 implicit 简化模式;在 sso.vue 单点登录界面被【获取】调用") |
| 86 | @ApiImplicitParams({ | 88 | @ApiImplicitParams({ |
| 87 | @ApiImplicitParam(name = "grant_type", required = true, value = "授权类型", example = "code", dataTypeClass = String.class), | 89 | @ApiImplicitParam(name = "grant_type", required = true, value = "授权类型", example = "code", dataTypeClass = String.class), |
| @@ -141,6 +143,7 @@ public class OAuth2OpenController { | @@ -141,6 +143,7 @@ public class OAuth2OpenController { | ||
| 141 | } | 143 | } |
| 142 | 144 | ||
| 143 | @DeleteMapping("/token") | 145 | @DeleteMapping("/token") |
| 146 | + @PermitAll | ||
| 144 | @ApiOperation(value = "删除访问令牌") | 147 | @ApiOperation(value = "删除访问令牌") |
| 145 | @ApiImplicitParam(name = "token", required = true, value = "访问令牌", example = "biu", dataTypeClass = String.class) | 148 | @ApiImplicitParam(name = "token", required = true, value = "访问令牌", example = "biu", dataTypeClass = String.class) |
| 146 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 | 149 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 |
| @@ -159,6 +162,7 @@ public class OAuth2OpenController { | @@ -159,6 +162,7 @@ public class OAuth2OpenController { | ||
| 159 | * 对应 Spring Security OAuth 的 CheckTokenEndpoint 类的 checkToken 方法 | 162 | * 对应 Spring Security OAuth 的 CheckTokenEndpoint 类的 checkToken 方法 |
| 160 | */ | 163 | */ |
| 161 | @PostMapping("/check-token") | 164 | @PostMapping("/check-token") |
| 165 | + @PermitAll | ||
| 162 | @ApiOperation(value = "校验访问令牌") | 166 | @ApiOperation(value = "校验访问令牌") |
| 163 | @ApiImplicitParam(name = "token", required = true, value = "访问令牌", example = "biu", dataTypeClass = String.class) | 167 | @ApiImplicitParam(name = "token", required = true, value = "访问令牌", example = "biu", dataTypeClass = String.class) |
| 164 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 | 168 | @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/sms/SmsCallbackController.java
| @@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestParam; | @@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestParam; | ||
| 15 | import org.springframework.web.bind.annotation.RestController; | 15 | import org.springframework.web.bind.annotation.RestController; |
| 16 | 16 | ||
| 17 | import javax.annotation.Resource; | 17 | import javax.annotation.Resource; |
| 18 | +import javax.annotation.security.PermitAll; | ||
| 18 | import javax.servlet.http.HttpServletRequest; | 19 | import javax.servlet.http.HttpServletRequest; |
| 19 | 20 | ||
| 20 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 21 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| @@ -28,6 +29,7 @@ public class SmsCallbackController { | @@ -28,6 +29,7 @@ public class SmsCallbackController { | ||
| 28 | private SmsSendService smsSendService; | 29 | private SmsSendService smsSendService; |
| 29 | 30 | ||
| 30 | @PostMapping("/yunpian") | 31 | @PostMapping("/yunpian") |
| 32 | + @PermitAll | ||
| 31 | @ApiOperation(value = "云片短信的回调", notes = "参见 https://www.yunpian.com/official/document/sms/zh_cn/domestic_push_report 文档") | 33 | @ApiOperation(value = "云片短信的回调", notes = "参见 https://www.yunpian.com/official/document/sms/zh_cn/domestic_push_report 文档") |
| 32 | @ApiImplicitParam(name = "sms_status", value = "发送状态", required = true, example = "[{具体内容}]", dataTypeClass = String.class) | 34 | @ApiImplicitParam(name = "sms_status", value = "发送状态", required = true, example = "[{具体内容}]", dataTypeClass = String.class) |
| 33 | @OperateLog(enable = false) | 35 | @OperateLog(enable = false) |
| @@ -38,6 +40,7 @@ public class SmsCallbackController { | @@ -38,6 +40,7 @@ public class SmsCallbackController { | ||
| 38 | } | 40 | } |
| 39 | 41 | ||
| 40 | @PostMapping("/aliyun") | 42 | @PostMapping("/aliyun") |
| 43 | + @PermitAll | ||
| 41 | @ApiOperation(value = "阿里云短信的回调", notes = "参见 https://help.aliyun.com/document_detail/120998.html 文档") | 44 | @ApiOperation(value = "阿里云短信的回调", notes = "参见 https://help.aliyun.com/document_detail/120998.html 文档") |
| 42 | @OperateLog(enable = false) | 45 | @OperateLog(enable = false) |
| 43 | public CommonResult<Boolean> receiveAliyunSmsStatus(HttpServletRequest request) throws Throwable { | 46 | public CommonResult<Boolean> receiveAliyunSmsStatus(HttpServletRequest request) throws Throwable { |
| @@ -47,6 +50,7 @@ public class SmsCallbackController { | @@ -47,6 +50,7 @@ public class SmsCallbackController { | ||
| 47 | } | 50 | } |
| 48 | 51 | ||
| 49 | @PostMapping("/tencent") | 52 | @PostMapping("/tencent") |
| 53 | + @PermitAll | ||
| 50 | @ApiOperation(value = "腾讯云短信的回调", notes = "参见 https://cloud.tencent.com/document/product/382/52077 文档") | 54 | @ApiOperation(value = "腾讯云短信的回调", notes = "参见 https://cloud.tencent.com/document/product/382/52077 文档") |
| 51 | @OperateLog(enable = false) | 55 | @OperateLog(enable = false) |
| 52 | public CommonResult<Boolean> receiveTencentSmsStatus(HttpServletRequest request) throws Throwable { | 56 | public CommonResult<Boolean> receiveTencentSmsStatus(HttpServletRequest request) throws Throwable { |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tenant/TenantController.java
| @@ -15,6 +15,7 @@ import org.springframework.security.access.prepost.PreAuthorize; | @@ -15,6 +15,7 @@ import org.springframework.security.access.prepost.PreAuthorize; | ||
| 15 | import org.springframework.web.bind.annotation.*; | 15 | import org.springframework.web.bind.annotation.*; |
| 16 | 16 | ||
| 17 | import javax.annotation.Resource; | 17 | import javax.annotation.Resource; |
| 18 | +import javax.annotation.security.PermitAll; | ||
| 18 | import javax.servlet.http.HttpServletResponse; | 19 | import javax.servlet.http.HttpServletResponse; |
| 19 | import javax.validation.Valid; | 20 | import javax.validation.Valid; |
| 20 | import java.io.IOException; | 21 | import java.io.IOException; |
| @@ -32,6 +33,7 @@ public class TenantController { | @@ -32,6 +33,7 @@ public class TenantController { | ||
| 32 | private TenantService tenantService; | 33 | private TenantService tenantService; |
| 33 | 34 | ||
| 34 | @GetMapping("/get-id-by-name") | 35 | @GetMapping("/get-id-by-name") |
| 36 | + @PermitAll | ||
| 35 | @ApiOperation(value = "使用租户名,获得租户编号", notes = "登录界面,根据用户的租户名,获得租户编号") | 37 | @ApiOperation(value = "使用租户名,获得租户编号", notes = "登录界面,根据用户的租户名,获得租户编号") |
| 36 | @ApiImplicitParam(name = "name", value = "租户名", required = true, example = "1024", dataTypeClass = Long.class) | 38 | @ApiImplicitParam(name = "name", value = "租户名", required = true, example = "1024", dataTypeClass = Long.class) |
| 37 | public CommonResult<Long> getTenantIdByName(@RequestParam("name") String name) { | 39 | public CommonResult<Long> getTenantIdByName(@RequestParam("name") String name) { |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/security/config/SecurityConfiguration.java deleted
| 1 | -package cn.iocoder.yudao.module.system.framework.security.config; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer; | ||
| 4 | -import org.springframework.context.annotation.Bean; | ||
| 5 | -import org.springframework.context.annotation.Configuration; | ||
| 6 | -import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
| 7 | -import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; | ||
| 8 | - | ||
| 9 | -/** | ||
| 10 | - * System 模块的 Security 配置 | ||
| 11 | - */ | ||
| 12 | -@Configuration("systemSecurityConfiguration") | ||
| 13 | -public class SecurityConfiguration { | ||
| 14 | - | ||
| 15 | - @Bean("systemAuthorizeRequestsCustomizer") | ||
| 16 | - public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() { | ||
| 17 | - return new AuthorizeRequestsCustomizer() { | ||
| 18 | - | ||
| 19 | - @Override | ||
| 20 | - public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) { | ||
| 21 | - // 登录的接口 | ||
| 22 | - registry.antMatchers(buildAdminApi("/system/auth/login")).permitAll(); | ||
| 23 | - registry.antMatchers(buildAdminApi("/system/auth/logout")).permitAll(); | ||
| 24 | - registry.antMatchers(buildAdminApi("/system/auth/refresh-token")).permitAll(); | ||
| 25 | - // 社交登陆的接口 | ||
| 26 | - registry.antMatchers(buildAdminApi("/system/auth/social-auth-redirect")).permitAll(); | ||
| 27 | - registry.antMatchers(buildAdminApi("/system/auth/social-login")).permitAll(); | ||
| 28 | - // 登录登录的接口 | ||
| 29 | - registry.antMatchers(buildAdminApi("/system/auth/sms-login")).permitAll(); | ||
| 30 | - registry.antMatchers(buildAdminApi("/system/auth/send-sms-code")).permitAll(); | ||
| 31 | - // 验证码的接口 | ||
| 32 | - registry.antMatchers(buildAdminApi("/system/captcha/**")).permitAll(); | ||
| 33 | - // 获得租户编号的接口 | ||
| 34 | - registry.antMatchers(buildAdminApi("/system/tenant/get-id-by-name")).permitAll(); | ||
| 35 | - // 短信回调 API | ||
| 36 | - registry.antMatchers(buildAdminApi("/system/sms/callback/**")).permitAll(); | ||
| 37 | - // OAuth2 API | ||
| 38 | - registry.antMatchers(buildAdminApi("/system/oauth2/token")).permitAll(); | ||
| 39 | - registry.antMatchers(buildAdminApi("/system/oauth2/check-token")).permitAll(); | ||
| 40 | - } | ||
| 41 | - | ||
| 42 | - }; | ||
| 43 | - } | ||
| 44 | - | ||
| 45 | -} |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/security/core/package-info.java deleted
yudao-server/src/main/resources/application.yaml
| @@ -77,6 +77,9 @@ yudao: | @@ -77,6 +77,9 @@ yudao: | ||
| 77 | web: | 77 | web: |
| 78 | admin-ui: | 78 | admin-ui: |
| 79 | url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址 | 79 | url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址 |
| 80 | + security: | ||
| 81 | + permit-all_urls: | ||
| 82 | + - /admin-ui/** # /resources/admin-ui 目录下的静态资源 | ||
| 80 | swagger: | 83 | swagger: |
| 81 | title: 管理后台 | 84 | title: 管理后台 |
| 82 | description: 提供管理员管理的所有功能 | 85 | description: 提供管理员管理的所有功能 |