Commit d8a7dc4a authored by zengchao's avatar zengchao
Browse files

-

parent a817503b
......@@ -4,7 +4,6 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.catalina.User;
import org.apache.commons.lang3.StringUtils;
import org.beetl.sql.core.engine.PageQuery;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -34,7 +33,7 @@ import com.ibeetl.admin.core.util.enums.GeneralStateEnum;
@Transactional
public class UserConsoleService extends CoreBaseService<CoreUser> {
@Autowired UserConsoleDao userDao;
@Autowired UserConsoleDao userConsoleDao;
@Autowired FileService fileService;
......@@ -48,7 +47,7 @@ public class UserConsoleService extends CoreBaseService<CoreUser> {
* @param query
*/
public void queryByCondtion(PageQuery<CoreUser> query) {
PageQuery<CoreUser> ret = userDao.queryByCondtion(query);
PageQuery<CoreUser> ret = userConsoleDao.queryByCondtion(query);
queryListAfter(ret.getList());
}
......@@ -60,7 +59,7 @@ public class UserConsoleService extends CoreBaseService<CoreUser> {
public void saveUser(CoreUser user) {
CoreUser query = new CoreUser();
query.setCode(user.getCode());
CoreUser dbUser = userDao.templateOne(query);
CoreUser dbUser = userConsoleDao.templateOne(query);
if (dbUser != null) {
throw new PlatformException("保存用户信息失败,用户已经存在");
}
......@@ -68,11 +67,11 @@ public class UserConsoleService extends CoreBaseService<CoreUser> {
user.setState(GeneralStateEnum.ENABLE.getValue());
user.setPassword(passwordEncryptService.password(user.getPassword()));
user.setDelFlag(DelFlagEnum.NORMAL.getValue());
userDao.insert(user, true);
userConsoleDao.insert(user, true);
if (StringUtils.isNotEmpty(user.getAttachmentId())) {
// 更新附件详细信息,关联到这个用户
fileService.updateFile(
user.getAttachmentId(), User.class.getSimpleName(), String.valueOf(user.getId()));
user.getAttachmentId(), user.getName(), String.valueOf(user.getId()));
}
}
......@@ -82,7 +81,7 @@ public class UserConsoleService extends CoreBaseService<CoreUser> {
* @param userId
*/
public CoreUser queryUserById(Long userId) {
return userDao.unique(userId);
return userConsoleDao.unique(userId);
}
/**
......@@ -92,7 +91,7 @@ public class UserConsoleService extends CoreBaseService<CoreUser> {
* @return
*/
public int updateSysUser(CoreUser user) {
return userDao.updateTemplateById(user);
return userConsoleDao.updateTemplateById(user);
}
/**
......@@ -111,7 +110,7 @@ public class UserConsoleService extends CoreBaseService<CoreUser> {
user = new CoreUser();
user.setId(userId);
user.setDelFlag(DelFlagEnum.DELETED.getValue());
userDao.updateTemplateById(user);
userConsoleDao.updateTemplateById(user);
}
/**
......@@ -122,7 +121,7 @@ public class UserConsoleService extends CoreBaseService<CoreUser> {
*/
public void batchDelSysUser(List<Long> userIds) {
try {
userDao.batchDelUserByIds(userIds);
userConsoleDao.batchDelUserByIds(userIds);
} catch (Exception e) {
throw new PlatformException("批量删除用户失败", e);
}
......@@ -135,13 +134,13 @@ public class UserConsoleService extends CoreBaseService<CoreUser> {
* @param userIds 用户id
*/
public void batchUpdateUserState(List<Long> userIds, GeneralStateEnum stateEnum) {
userDao.batchUpdateUserState(userIds, stateEnum);
userConsoleDao.batchUpdateUserState(userIds, stateEnum);
}
/**
* 重置用户密码
*
* @param uId
* @param id
* @param password
*/
public int resetPassword(Long id, String password) {
......@@ -149,11 +148,11 @@ public class UserConsoleService extends CoreBaseService<CoreUser> {
user.setId(id);
user.setPassword(passwordEncryptService.password(password));
user.setUpdateTime(new Date());
return userDao.updateTemplateById(user);
return userConsoleDao.updateTemplateById(user);
}
public List<CoreUserRole> getUserRoles(UserRoleQuery roleQuery) {
return userDao.queryUserRole(
return userConsoleDao.queryUserRole(
roleQuery.getUserId(), roleQuery.getOrgId(), roleQuery.getRoleId());
}
......@@ -175,7 +174,7 @@ public class UserConsoleService extends CoreBaseService<CoreUser> {
}
public List<UserExcelExportData> queryExcel(PageQuery<CoreUser> query) {
PageQuery<CoreUser> ret = userDao.queryByCondtion(query);
PageQuery<CoreUser> ret = userConsoleDao.queryByCondtion(query);
List<CoreUser> list = ret.getList();
OrgItem orgRoot = platformService.buildOrg();
List<UserExcelExportData> items = new ArrayList<>();
......
......@@ -4,7 +4,14 @@ user.id=1
user.orgId=1
#\u6253\u5F00\u5BA1\u8BA1\u529F\u80FD\uFF0C\u5F00\u53D1\u6A21\u5F0F\u5E94\u8BE5\u5173\u95ED
audit.enable=false
server.port=8080
server.undertow.accesslog.enabled=true
server.undertow.io-threads=4
server.undertow.worker-threads=20
server.undertow.buffer-size=4096
server.undertow.direct-buffers=true
spring.datasource.baseDataSource.url=jdbc:mysql://127.0.0.1:3306/starter?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false&useInformationSchema=true
spring.datasource.baseDataSource.username=root
spring.datasource.baseDataSource.password=123456
......@@ -15,7 +22,6 @@ beetl.suffix=html
beetlsql.ds.baseDataSource.basePackage=com
beetlsql.ds.baseDataSource.dbStyle=org.beetl.sql.core.db.MySqlStyle
#beetlsql.basePackage=com.ibeetl,com.xxx.yourpackage
#\u6709\u4E00\u4E2A\u6570\u636E\u6E90\u547D\u540D\u4E3AbaseDataSource,\u4F60\u53EF\u4EE5\u6DFB\u52A0\u591A\u6570\u636E\u6E90
beetlsql.mutiple.datasource=baseDataSource
......
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>admin-core</artifactId>
......@@ -19,10 +20,20 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
......
......@@ -5,11 +5,25 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 参见 {@link com.ibeetl.admin.core.conf.RequestBodyPlusProcessor} 解析
* @author 一日看尽长安花
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestBodyPlus {
/*写入一个json path。默认直接将json转换为被注解的参数的类型对象*/
/**
* 用一个json path 将json请求转换为被注解的参数的类型对象。<br/>
* 意图避免原本的{@link org.springframework.web.bind.annotation.RequestBody} 注解必须创建新的对象接收参数,降低项目的类数量<br/>
* 如果默认未空值,则整个json请求都将被转换为参数类型。<br/>
* 以参数类型为目标,有如下情况:<br/>
* Object : json str = {...} ;最终转换为Object<br/>
* Collect : json str = {...} -> [{...}] ; 以集合的泛型类型(如果泛型不存在,以Object为目标)为目标转换为集合中的一个对象(整个json作为一个元素)
* Object : json str = [{....}] ;最终转换为Object<br/>
* Collect : json str = [{...}] -> [{...}] ; 以集合的泛型类型(如果泛型不存在,以Object为目标)为目标转换为集合中的一个对象(整个json作为一个元素)<br/>
* 以上遵循{@link cn.hutool.json.JSONUtil} 的转换规则,忽视转换错误,不能转换时,返回一个空值对象
*/
String value() default "";
boolean required() default true;
}
package com.ibeetl.admin.core.conf;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.TypeUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ibeetl.admin.core.annotation.RequestBodyPlus;
import com.ibeetl.admin.core.entity.CoreOrg;
......@@ -19,24 +18,18 @@ import com.ibeetl.admin.core.service.CoreUserService;
import com.ibeetl.admin.core.util.HttpRequestLocal;
import com.ibeetl.admin.core.util.JoseJwtUtil;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import jdk.nashorn.internal.ir.ReturnNode;
import org.beetl.core.GroupTemplate;
import org.beetl.ext.spring.BeetlGroupUtilConfiguration;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Conventions;
import org.springframework.core.MethodParameter;
import org.springframework.core.env.Environment;
import org.springframework.format.FormatterRegistry;
......@@ -44,16 +37,9 @@ import org.springframework.format.datetime.DateFormatter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.util.Assert;
import org.springframework.validation.BindingResult;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
......@@ -65,7 +51,6 @@ import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import sun.plugin2.util.ColorUtil;
@Configuration
public class MVCConf implements WebMvcConfigurer, InitializingBean {
......@@ -94,8 +79,7 @@ public class MVCConf implements WebMvcConfigurer, InitializingBean {
public void addInterceptors(InterceptorRegistry registry) {
registry
.addInterceptor(new SessionInterceptor(httpRequestLocal, userService))
.addPathPatterns("/**")
.excludePathPatterns("/user/login", "/error", "/logout");
.addPathPatterns("/**");
// super.addInterceptors(registry);
}
......@@ -142,6 +126,11 @@ class SessionInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(
HttpServletRequest request, HttpServletResponse response, Object handler) {
httpRequestLocal.set(request);
if (StrUtil.containsAny(request.getRequestURI(), "/user/login", "/error", "/logout")) {
return true;
}
String token = request.getHeader(HttpHeaders.AUTHORIZATION);
Map<String, Object> payload = JoseJwtUtil.parsePayload(token);
if (payload.isEmpty()) {
......@@ -161,7 +150,6 @@ class SessionInterceptor implements HandlerInterceptor {
requestSession.setAttribute(CorePlatformService.ACCESS_USER_ORGS, orgs);
requestSession.setAttribute("ip", httpRequestLocal.getRequestIP());
}
httpRequestLocal.set(request);
return true;
}
......@@ -181,9 +169,10 @@ class SessionInterceptor implements HandlerInterceptor {
}
}
/** 自定义注解,用json path 的方式注入json类型的参数 */
/** 自定义SpringMVC的controller参数注解 {@link RequestBodyPlus} 的注入解析,用json path 的方式注入json请求的参数 */
class RequestBodyPlusProcessor extends AbstractMessageConverterMethodProcessor {
private static final ThreadLocal<String> bodyLocal = ThreadLocal.withInitial(() -> null);
private static final ThreadLocal<String> bodyLocal = ThreadLocal.withInitial(() -> "{}");
protected RequestBodyPlusProcessor(List<HttpMessageConverter<?>> converters) {
super(converters);
......@@ -203,10 +192,10 @@ class RequestBodyPlusProcessor extends AbstractMessageConverterMethodProcessor {
throws Exception {
parameter = parameter.nestedIfOptional();
/*非json请求过滤*/
Class<?> parameterType = parameter.getNestedParameterType();
Class<?> parameterClass = parameter.getNestedParameterType();
if (!StrUtil.containsAny(
webRequest.getHeader(HttpHeaders.CONTENT_TYPE), MediaType.APPLICATION_JSON_VALUE)) {
return ReflectUtil.newInstanceIfPossible(parameterType);
return ReflectUtil.newInstanceIfPossible(parameterClass);
}
HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
......@@ -214,23 +203,35 @@ class RequestBodyPlusProcessor extends AbstractMessageConverterMethodProcessor {
ServletServerHttpRequest inputMessage = new ServletServerHttpRequest(servletRequest);
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
String jsonBody =
Optional.ofNullable(bodyLocal.get())
.orElseGet(
() -> {
String jsonBody;
try {
bodyLocal.set(stringHttpMessageConverter.read(String.class, inputMessage));
String readBody = stringHttpMessageConverter.read(String.class, inputMessage);
/*每一个参数的注入都会读取一次输入流,但是request的输入流不可重复读,所以需要保持下来*/
if (StrUtil.isBlank(readBody)) {
jsonBody = bodyLocal.get();
} else {
bodyLocal.set(readBody);
jsonBody = bodyLocal.get();
}
} catch (IOException e) {
logger.error("can't read request body by input stream : {}", e);
logger.error("Can't read request body by input stream : {}", e);
jsonBody = bodyLocal.get();
}
return bodyLocal.get();
});
RequestBodyPlus requestBodyPlus = parameter.getParameterAnnotation(RequestBodyPlus.class);
JSON json = JSONUtil.parse(jsonBody);
Object parseVal = json.getByPath(requestBodyPlus.value(), parameterType);
/*TODO 待将json转成对象*/
System.out.println(JSONUtil.parse("{'users':[ {'user':{'name':'lisi'}} ]}").getByPath("users"));
Object parseVal = json.getByPath(requestBodyPlus.value(), parameterClass);
if (parseVal instanceof Map) {
JSONObject jsonObject = JSONUtil.parseObj(parseVal);
parseVal = JSONUtil.toBean(jsonObject, parameter.getNestedGenericParameterType(), true);
} else if (parseVal instanceof List) {
JSONArray jsonArray = JSONUtil.parseArray(parseVal);
Type parameterType = TypeUtil.getTypeArgument(parameter.getNestedGenericParameterType());
Class parameterTypeClass =
null == parameterType ? Object.class : ClassUtil.loadClass(parameterType.getTypeName());
parseVal = JSONUtil.toList(jsonArray, parameterTypeClass);
}
return parseVal;
}
......
package com.ibeetl.admin.core.util;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Map;
import java.util.Random;
import org.jose4j.jwk.RsaJsonWebKey;
......@@ -20,28 +16,35 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 基于jose4j的jwt库工具类。 包括:生成,反生成
* 基于jose4j的jwt库工具类。 包括:生成,验证,解析负载。<br/>
* 可以用对称加密算法在此对token进行加密,逻辑上可以每隔一周或者一天,动态生成对称加密算法的密钥,然后防止破解。<br/>
* 这样可以用jwt来承担更多的数据传递。至于客官怎么选择——萝卜青菜各有所爱<br/>
*
* @author 一日看尽长安花
*/
public class JoseJwtUtil {
private static Logger logger = LoggerFactory.getLogger(JoseJwtUtil.class);
public static String generateJwtJson(String uid, float expiration) {
public static String generateJwtJson(String uid) {
JwtClaims jwtClaims = new JwtClaims();
jwtClaims.setExpirationTimeMinutesInTheFuture(expiration); // 以分钟为单位的过期时间
jwtClaims.setIssuer("Issuer"); // who creates the token and signs it
jwtClaims.setAudience("Audience"); // to whom the token is intended to be sent
jwtClaims.setGeneratedJwtId(); // a unique identifier for the token
jwtClaims.setIssuedAtToNow(); // when the token was issued/created (now)
jwtClaims.setNotBeforeMinutesInThePast(
2); // time before which the token is not yet valid (2 minutes ago)
jwtClaims.setExpirationTimeMinutesInTheFuture(30);
/* 以分钟为单位的过期时间 */
/* who creates the token and signs it */
jwtClaims.setIssuer("Issuer");
/* to whom the token is intended to be sent */
jwtClaims.setAudience("Audience");
/* a unique identifier for the token */
jwtClaims.setGeneratedJwtId();
/* when the token was issued/created (now) */
jwtClaims.setIssuedAtToNow();
/* time before which the token is not yet valid (2 minutes ago) */
jwtClaims.setNotBeforeMinutesInThePast(2);
/*主题:签证*/
jwtClaims.setSubject("Bearer");
/*用户id*/
jwtClaims.setClaim("uid", uid);
/*登录时间*/
jwtClaims.setClaim("ltm", new Date().getTime());
jwtClaims.setClaim("ltm", System.currentTimeMillis());
RsaJsonWebKey rsaJsonWebKey = RsaJsonWebKeyBuilder.getRasJsonWebKeyInstance();
JsonWebSignature jsonWebSignature = new JsonWebSignature();
......
package com.ibeetl.admin.core.web;
import cn.hutool.core.map.MapUtil;
import com.ibeetl.admin.core.annotation.RequestBodyPlus;
import com.ibeetl.admin.core.entity.CoreOrg;
import com.ibeetl.admin.core.entity.CoreUser;
import com.ibeetl.admin.core.rbac.UserLoginInfo;
import com.ibeetl.admin.core.rbac.tree.MenuItem;
import com.ibeetl.admin.core.service.CorePlatformService;
import com.ibeetl.admin.core.service.CoreUserService;
import com.ibeetl.admin.core.util.HttpRequestLocal;
import com.ibeetl.admin.core.util.JoseJwtUtil;
import com.ibeetl.admin.core.util.PlatformException;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.ibeetl.admin.core.entity.CoreOrg;
import com.ibeetl.admin.core.entity.CoreUser;
import com.ibeetl.admin.core.rbac.UserLoginInfo;
import com.ibeetl.admin.core.rbac.tree.MenuItem;
import com.ibeetl.admin.core.service.CorePlatformService;
import com.ibeetl.admin.core.service.CoreUserService;
import com.ibeetl.admin.core.util.HttpRequestLocal;
import com.ibeetl.admin.core.util.PlatformException;
@Controller
public class IndexController {
......@@ -63,12 +59,11 @@ public class IndexController {
return view;
}*/
@CrossOrigin
@PostMapping("/user/login")
@ResponseBody
public Object login(
@RequestBodyPlus("username") String username, String password, @RequestBodyPlus Map params) {
@RequestBodyPlus("username") String username, @RequestBodyPlus("password") String password) {
UserLoginInfo info = userService.login(username, password);
System.out.println(params);
if (info == null) {
throw new PlatformException("用户名密码错误");
}
......@@ -84,7 +79,9 @@ public class IndexController {
info.setCurrentOrg(currentOrg);
// 记录登录信息到session
this.platformService.setLoginUser(info.getUser(), info.getCurrentOrg(), info.getOrgs());
return null;
Map<Object, Object> resultMap = MapUtil.builder()
.put("token", JoseJwtUtil.generateJwtJson(String.valueOf(user.getId()))).build();
return JsonResult.success(resultMap);
}
@RequestMapping("/index.do")
......
......@@ -32,8 +32,16 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
......
......@@ -116,7 +116,7 @@ export default {
return {
loginForm: {
username: 'admin',
password: '111111'
password: '123456'
},
loginRules: {
username: [
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment