diff --git a/eladmin-common/src/main/java/me/zhengjie/utils/enums/RequestMethodEnum.java b/eladmin-common/src/main/java/me/zhengjie/utils/enums/RequestMethodEnum.java new file mode 100644 index 00000000..1b65c786 --- /dev/null +++ b/eladmin-common/src/main/java/me/zhengjie/utils/enums/RequestMethodEnum.java @@ -0,0 +1,74 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author Zheng Jie + * @website https://el-admin.vip + * @description + * @date 2020-06-10 + **/ +@Getter +@AllArgsConstructor +public enum RequestMethodEnum { + + /** + * 搜寻 @AnonymousGetMapping + */ + GET("GET"), + + /** + * 搜寻 @AnonymousPostMapping + */ + POST("POST"), + + /** + * 搜寻 @AnonymousPutMapping + */ + PUT("PUT"), + + /** + * 搜寻 @AnonymousPatchMapping + */ + PATCH("PATCH"), + + /** + * 搜寻 @AnonymousDeleteMapping + */ + DELETE("DELETE"), + + /** + * 否则就是所有 Request 接口都放行 + */ + ALL("All"); + + /** + * Request 类型 + */ + private final String type; + + public static RequestMethodEnum find(String type) { + for (RequestMethodEnum value : RequestMethodEnum.values()) { + if (type.equals(value.getType())) { + return value; + } + } + return ALL; + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java index 5857f5e4..2f110398 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java @@ -18,6 +18,7 @@ package me.zhengjie.modules.security.config; import lombok.RequiredArgsConstructor; import me.zhengjie.annotation.AnonymousAccess; import me.zhengjie.modules.security.security.*; +import me.zhengjie.utils.enums.RequestMethodEnum; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -31,13 +32,12 @@ 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.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.filter.CorsFilter; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * @author Zheng Jie @@ -70,14 +70,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { protected void configure(HttpSecurity httpSecurity) throws Exception { // 搜寻匿名标记 url: @AnonymousAccess Map handlerMethodMap = applicationContext.getBean(RequestMappingHandlerMapping.class).getHandlerMethods(); - Set anonymousUrls = new HashSet<>(); - for (Map.Entry infoEntry : handlerMethodMap.entrySet()) { - HandlerMethod handlerMethod = infoEntry.getValue(); - AnonymousAccess anonymousAccess = handlerMethod.getMethodAnnotation(AnonymousAccess.class); - if (null != anonymousAccess) { - anonymousUrls.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); - } - } + // 获取匿名标记 + Map> anonymousUrls = getAnonymousUrl(handlerMethodMap); httpSecurity // 禁用 CSRF .csrf().disable() @@ -86,18 +80,15 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { .exceptionHandling() .authenticationEntryPoint(authenticationErrorHandler) .accessDeniedHandler(jwtAccessDeniedHandler) - // 防止iframe 造成跨域 .and() .headers() .frameOptions() .disable() - // 不创建会话 .and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) - .and() .authorizeRequests() // 静态资源等等 @@ -121,13 +112,69 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { .antMatchers("/druid/**").permitAll() // 放行OPTIONS请求 .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() - // 自定义匿名访问所有url放行 : 允许匿名和带权限以及登录用户访问 - .antMatchers(anonymousUrls.toArray(new String[0])).permitAll() + // 自定义匿名访问所有url放行:允许匿名和带Token访问,细腻化到每个 Request 类型 + // GET + .antMatchers(HttpMethod.GET, anonymousUrls.get(RequestMethodEnum.GET.getType()).toArray(new String[0])).permitAll() + // POST + .antMatchers(HttpMethod.POST, anonymousUrls.get(RequestMethodEnum.POST.getType()).toArray(new String[0])).permitAll() + // PUT + .antMatchers(HttpMethod.PUT, anonymousUrls.get(RequestMethodEnum.PUT.getType()).toArray(new String[0])).permitAll() + // PATCH + .antMatchers(HttpMethod.PATCH, anonymousUrls.get(RequestMethodEnum.PATCH.getType()).toArray(new String[0])).permitAll() + // DELETE + .antMatchers(HttpMethod.DELETE, anonymousUrls.get(RequestMethodEnum.DELETE.getType()).toArray(new String[0])).permitAll() + // 所有类型的接口都放行 + .antMatchers(anonymousUrls.get(RequestMethodEnum.ALL.getType()).toArray(new String[0])).permitAll() // 所有请求都需要认证 .anyRequest().authenticated() .and().apply(securityConfigurerAdapter()); } + private Map> getAnonymousUrl(Map handlerMethodMap) { + Map> anonymousUrls = new HashMap<>(6); + Set get = new HashSet<>(); + Set post = new HashSet<>(); + Set put = new HashSet<>(); + Set patch = new HashSet<>(); + Set delete = new HashSet<>(); + Set all = new HashSet<>(); + for (Map.Entry infoEntry : handlerMethodMap.entrySet()) { + HandlerMethod handlerMethod = infoEntry.getValue(); + AnonymousAccess anonymousAccess = handlerMethod.getMethodAnnotation(AnonymousAccess.class); + if (null != anonymousAccess) { + List requestMethods = new ArrayList<>(infoEntry.getKey().getMethodsCondition().getMethods()); + RequestMethodEnum request = RequestMethodEnum.find(requestMethods.size() == 0 ? RequestMethodEnum.ALL.getType() : requestMethods.get(0).name()); + switch (Objects.requireNonNull(request)){ + case GET: + get.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case POST: + post.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case PUT: + put.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case PATCH: + patch.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case DELETE: + delete.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + default: + all.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + } + } + } + anonymousUrls.put(RequestMethodEnum.GET.getType(), get); + anonymousUrls.put(RequestMethodEnum.POST.getType(), post); + anonymousUrls.put(RequestMethodEnum.PUT.getType(), put); + anonymousUrls.put(RequestMethodEnum.PATCH.getType(), patch); + anonymousUrls.put(RequestMethodEnum.DELETE.getType(), delete); + anonymousUrls.put(RequestMethodEnum.ALL.getType(), all); + return anonymousUrls; + } + private TokenConfigurer securityConfigurerAdapter() { return new TokenConfigurer(tokenProvider); } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginProperties.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginProperties.java index 48f05ad0..7d948ed0 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginProperties.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginProperties.java @@ -19,14 +19,12 @@ package me.zhengjie.modules.security.config.bean; import com.wf.captcha.*; import com.wf.captcha.base.Captcha; import me.zhengjie.exception.BadConfigurationException; - import java.util.Objects; /** * 配置文件读取 - * - * @author: liaojinlong - * @date: loginCode.length0loginCode.length0/6/10 17:loginCode.length6 + * @author liaojinlong + * @date loginCode.length0loginCode.length0/6/10 17:loginCode.length6 */ public class LoginProperties { @@ -65,8 +63,7 @@ public class LoginProperties { loginCode.setCodeType(LoginCodeEnum.arithmetic); } } - Captcha captcha = switchCaptcha(loginCode); - return captcha; + return switchCaptcha(loginCode); } /** @@ -100,6 +97,7 @@ public class LoginProperties { case spec: captcha = new SpecCaptcha(loginCode.getWidth(), loginCode.getHeight()); captcha.setLen(loginCode.getLength()); + break; default: throw new BadConfigurationException("验证码配置信息错误!!!正确配置查看 me.zhengjie.modules.security.config.bean.LoginCodeEnum "); } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/UserServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/UserServiceImpl.java index ddba492c..5c1e5ae9 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/UserServiceImpl.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/UserServiceImpl.java @@ -109,6 +109,10 @@ public class UserServiceImpl implements UserService { redisUtils.del("menu::user:" + resources.getId()); redisUtils.del("role::auth:" + resources.getId()); } + // 如果用户名称修改 + if(!resources.getUsername().equals(user.getUsername())){ + redisUtils.del("user::username:" + user.getUsername()); + } user.setUsername(resources.getUsername()); user.setEmail(resources.getEmail()); user.setEnabled(resources.getEnabled()); diff --git a/eladmin-system/src/main/resources/config/application-dev.yml b/eladmin-system/src/main/resources/config/application-dev.yml index 12cf5bcc..0811295c 100644 --- a/eladmin-system/src/main/resources/config/application-dev.yml +++ b/eladmin-system/src/main/resources/config/application-dev.yml @@ -50,8 +50,8 @@ login: single: false # 验证码 login-code: - # 验证码类型配置 - code-type: chinese_gif + # 验证码类型配置 查看 LoginProperties 类 + code-type: arithmetic # 登录图形验证码有效时间/分钟 expiration: 2 # 验证码高度 @@ -59,7 +59,7 @@ login: # 验证码宽度 heigth: 36 # 内容长度 - length: 3 + length: 2 #jwt jwt: @@ -91,7 +91,6 @@ swagger: ip: local-parsing: true - # 文件存储路径 file: mac: diff --git a/eladmin-system/src/main/resources/config/application-prod.yml b/eladmin-system/src/main/resources/config/application-prod.yml index 1c16b5a8..cd26ca0f 100644 --- a/eladmin-system/src/main/resources/config/application-prod.yml +++ b/eladmin-system/src/main/resources/config/application-prod.yml @@ -52,7 +52,7 @@ login: single: false # 验证码 login-code: - # 验证码类型配置 + # 验证码类型配置 查看 LoginProperties 类 code-type: chinese_gif # 登录图形验证码有效时间/分钟 expiration: 2 @@ -61,7 +61,7 @@ login: # 验证码宽度 heigth: 36 # 内容长度 - length: 3 + length: 2 #jwt jwt: diff --git a/eladmin-system/src/main/resources/config/application.yml b/eladmin-system/src/main/resources/config/application.yml index ee547363..a7123167 100644 --- a/eladmin-system/src/main/resources/config/application.yml +++ b/eladmin-system/src/main/resources/config/application.yml @@ -50,23 +50,6 @@ qiniu: code: expiration: 300 -# 登录相关配置 -login: - # 是否限制单用户登录 - single: false - # 验证码 - login-code: - # 验证码类型配置 - code-type: chinese_gif - # 登录图形验证码有效时间/分钟 - expiration: 2 - # 验证码高度 - width: 111 - # 验证码宽度 - heigth: 36 - # 内容长度 - length: 3 - #密码加密传输,前端公钥加密,后端私钥解密 rsa: private_key: MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A==