mirror of https://github.com/elunez/eladmin
Merge branch 'source'
# Conflicts: # eladmin-system/src/main/java/me/zhengjie/modules/security/config/bean/LoginProperties.java # eladmin-system/src/main/resources/config/application-dev.yml # eladmin-system/src/main/resources/config/application-prod.yml # eladmin-system/src/main/resources/config/application.ymlpull/411/head
commit
a5fc181b3f
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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<RequestMappingInfo, HandlerMethod> handlerMethodMap = applicationContext.getBean(RequestMappingHandlerMapping.class).getHandlerMethods();
|
||||
Set<String> anonymousUrls = new HashSet<>();
|
||||
for (Map.Entry<RequestMappingInfo, HandlerMethod> infoEntry : handlerMethodMap.entrySet()) {
|
||||
HandlerMethod handlerMethod = infoEntry.getValue();
|
||||
AnonymousAccess anonymousAccess = handlerMethod.getMethodAnnotation(AnonymousAccess.class);
|
||||
if (null != anonymousAccess) {
|
||||
anonymousUrls.addAll(infoEntry.getKey().getPatternsCondition().getPatterns());
|
||||
}
|
||||
}
|
||||
// 获取匿名标记
|
||||
Map<String, Set<String>> 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<String, Set<String>> getAnonymousUrl(Map<RequestMappingInfo, HandlerMethod> handlerMethodMap) {
|
||||
Map<String, Set<String>> anonymousUrls = new HashMap<>(6);
|
||||
Set<String> get = new HashSet<>();
|
||||
Set<String> post = new HashSet<>();
|
||||
Set<String> put = new HashSet<>();
|
||||
Set<String> patch = new HashSet<>();
|
||||
Set<String> delete = new HashSet<>();
|
||||
Set<String> all = new HashSet<>();
|
||||
for (Map.Entry<RequestMappingInfo, HandlerMethod> infoEntry : handlerMethodMap.entrySet()) {
|
||||
HandlerMethod handlerMethod = infoEntry.getValue();
|
||||
AnonymousAccess anonymousAccess = handlerMethod.getMethodAnnotation(AnonymousAccess.class);
|
||||
if (null != anonymousAccess) {
|
||||
List<RequestMethod> 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);
|
||||
}
|
||||
|
|
|
@ -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 ");
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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==
|
||||
|
|
Loading…
Reference in New Issue