diff --git a/.gitignore b/.gitignore index a1c2a238a9..6cbce7691b 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,7 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* +/.idea/ +target/ +*.iml +.DS_Store diff --git a/fit2cloud-commons/fit2cloud-common-auth/pom.xml b/fit2cloud-commons/fit2cloud-common-auth/pom.xml new file mode 100644 index 0000000000..94d5fb5a3f --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/pom.xml @@ -0,0 +1,56 @@ + + + + fit2cloud-commons + com.fit2cloud + 1.0-SNAPSHOT + + 4.0.0 + + fit2cloud-common-auth + + + + org.apache.shiro + shiro-spring + ${shiro.version} + + + + com.auth0 + java-jwt + ${jwt.version} + + + com.fit2cloud + fit2cloud-common-db + 1.0-SNAPSHOT + + + + org.apache.commons + commons-text + 1.9 + + + + org.springframework.boot + spring-boot-starter-cache + + + + net.sf.ehcache + ehcache-core + ${ehcache.version} + + + + + + + + + + \ No newline at end of file diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/api/UserApi.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/api/UserApi.java new file mode 100644 index 0000000000..71a8b84c5a --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/api/UserApi.java @@ -0,0 +1,59 @@ +package com.fit2cloud.commons.auth.api; + +import cn.hutool.core.util.StrUtil; +import com.fit2cloud.commons.auth.bean.LoginDto; +import com.fit2cloud.commons.auth.bean.UserBean; +import com.fit2cloud.commons.auth.bean.UserInfo; +import com.fit2cloud.commons.auth.service.UserService; +import com.fit2cloud.commons.auth.util.JWTUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import javax.servlet.http.HttpServletRequest; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@RestController +public class UserApi { + + @Autowired + private UserService userService; + + @PostMapping("/login") + public Map login(@RequestBody LoginDto loginDto){ + String username = loginDto.getUsername(); + String password = loginDto.getPassword(); + String realPwd = userService.getPassword(username); + if (StrUtil.isEmpty(realPwd)){ + throw new RuntimeException("没有该用户!"); + } + if (!StrUtil.equals(realPwd, password)){ + throw new RuntimeException("密码错误!"); + } + Map result = new HashMap<>(); + result.put("token", JWTUtil.sign(username, password)); + return result; + } + + @GetMapping("/info") + public UserInfo getUserInfo(){ + ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + HttpServletRequest request = requestAttributes.getRequest(); + String token = request.getHeader("Authorization"); + String username = JWTUtil.getUsername(token); + UserBean user = userService.getUser(username); + String[] split = user.getRole().split(","); + List strings = Arrays.asList(split); + UserInfo info = UserInfo.builder().name(user.getUsername()).roles(strings).avatar("http://fit2cloud.com").introduction(user.getUsername()).build(); + return info; + } + + @PostMapping("/logout") + public String logout(){ + return "success"; + } + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/bean/ExtPermissionBean.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/bean/ExtPermissionBean.java new file mode 100644 index 0000000000..14a031bc84 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/bean/ExtPermissionBean.java @@ -0,0 +1,19 @@ +package com.fit2cloud.commons.auth.bean; + +import com.fit2cloud.commons.auth.entity.Permission; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ExtPermissionBean extends Permission { + private String url; + + public PermissionKey getKey(){ + return PermissionKey.builder().resourceId(getResourceId()).url(url).build(); + } +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/bean/LoginDto.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/bean/LoginDto.java new file mode 100644 index 0000000000..2102f71883 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/bean/LoginDto.java @@ -0,0 +1,20 @@ +package com.fit2cloud.commons.auth.bean; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class LoginDto implements Serializable { + + private String username; + + private String password; + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/bean/PermissionKey.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/bean/PermissionKey.java new file mode 100644 index 0000000000..75a4ae23af --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/bean/PermissionKey.java @@ -0,0 +1,41 @@ +package com.fit2cloud.commons.auth.bean; + + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 作为HashMap key + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PermissionKey { + + private String resourceId; + + private String url; + + /** + * 重写equals方法必须重写hashCode方法 + * @param anObject + * @return + */ + public boolean equals(Object anObject) { + if (this == anObject)return true; + if (anObject instanceof PermissionKey){ + PermissionKey current = (PermissionKey) anObject; + if (current == null || current.resourceId == null)return false; + return current.resourceId.equals(this.resourceId); + } + return false; + } + + public int hashCode() { + return resourceId.hashCode(); + } + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/bean/UserBean.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/bean/UserBean.java new file mode 100644 index 0000000000..0917ac9d08 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/bean/UserBean.java @@ -0,0 +1,22 @@ +package com.fit2cloud.commons.auth.bean; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class UserBean { + + private String username; + + private String password; + + private String role; + + private String permission; +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/bean/UserInfo.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/bean/UserInfo.java new file mode 100644 index 0000000000..8707d3bdf9 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/bean/UserInfo.java @@ -0,0 +1,26 @@ +package com.fit2cloud.commons.auth.bean; + + +import com.fit2cloud.commons.auth.entity.User; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class UserInfo implements Serializable { + + private List roles; + + private String introduction; + + private String name; + + private String avatar; +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/config/CorsConfig.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/config/CorsConfig.java new file mode 100644 index 0000000000..5c406daec3 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/config/CorsConfig.java @@ -0,0 +1,32 @@ +package com.fit2cloud.commons.auth.config; + + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + +import java.util.Collections; + +@Configuration +public class CorsConfig { + + @Bean + public CorsFilter corsFilter() { + CorsConfiguration corsConfiguration = new CorsConfiguration(); + //1,允许任何来源 + corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*")); + //2,允许任何请求头 + corsConfiguration.addAllowedHeader(CorsConfiguration.ALL); + //3,允许任何方法 + corsConfiguration.addAllowedMethod(CorsConfiguration.ALL); + //4,允许凭证 + corsConfiguration.setAllowCredentials(true); + + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", corsConfiguration); + return new CorsFilter(source); + } + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/config/F2cRealm.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/config/F2cRealm.java new file mode 100644 index 0000000000..d8b1c6ef01 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/config/F2cRealm.java @@ -0,0 +1,77 @@ +package com.fit2cloud.commons.auth.config; + +import com.fit2cloud.commons.auth.bean.UserBean; +import com.fit2cloud.commons.auth.service.UserService; +import com.fit2cloud.commons.auth.util.JWTUtil; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.AuthenticationInfo; +import org.apache.shiro.authc.AuthenticationToken; +import org.apache.shiro.authc.SimpleAuthenticationInfo; +import org.apache.shiro.authz.AuthorizationInfo; +import org.apache.shiro.authz.SimpleAuthorizationInfo; +import org.apache.shiro.realm.AuthorizingRealm; +import org.apache.shiro.subject.PrincipalCollection; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +@Component +public class F2cRealm extends AuthorizingRealm { + + private static final Logger LOGGER = LogManager.getLogger(F2cRealm.class); + + @Autowired + private UserService userService; + + + /** + * 大坑!,必须重写此方法,不然Shiro会报错 + */ + @Override + public boolean supports(AuthenticationToken token) { + return token instanceof JWTToken; + } + + /** + * 只有当需要检测用户权限的时候才会调用此方法,例如checkRole,checkPermission之类的 + */ + @Override + protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { + String username = JWTUtil.getUsername(principals.toString()); + UserBean user = userService.getUser(username); + SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); + Set role = new HashSet<>(Arrays.asList(user.getRole().split(","))); + simpleAuthorizationInfo.addRoles(role); + Set permission = new HashSet<>(Arrays.asList(user.getPermission().split(","))); + simpleAuthorizationInfo.addStringPermissions(permission); + return simpleAuthorizationInfo; + } + + /** + * 默认使用此方法进行用户名正确与否验证,错误抛出异常即可。 + */ + @Override + protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException { + String token = (String) auth.getCredentials(); + // 解密获得username,用于和数据库进行对比 + String username = JWTUtil.getUsername(token); + if (username == null) { + throw new AuthenticationException("token invalid"); + } + + UserBean userBean = userService.getUser(username); + if (userBean == null) { + throw new AuthenticationException("User didn't existed!"); + } + + if (! JWTUtil.verify(token, username, userBean.getPassword())) { + throw new AuthenticationException("Username or password error"); + } + + return new SimpleAuthenticationInfo(token, token, "my_realm"); + } +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/config/JWTToken.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/config/JWTToken.java new file mode 100644 index 0000000000..2b6a704229 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/config/JWTToken.java @@ -0,0 +1,22 @@ +package com.fit2cloud.commons.auth.config; + +import org.apache.shiro.authc.AuthenticationToken; + +public class JWTToken implements AuthenticationToken { + + private String token; + + public JWTToken(String token) { + this.token = token; + } + + @Override + public Object getPrincipal() { + return token; + } + + @Override + public Object getCredentials() { + return token; + } +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/config/ShiroConfig.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/config/ShiroConfig.java new file mode 100644 index 0000000000..ff2d675a0a --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/config/ShiroConfig.java @@ -0,0 +1,83 @@ +package com.fit2cloud.commons.auth.config; + +import com.fit2cloud.commons.auth.filter.F2CLogoutFilter; +import com.fit2cloud.commons.auth.filter.F2CPermissionsFilter; +import com.fit2cloud.commons.auth.filter.F2CRolesFilter; +import com.fit2cloud.commons.auth.filter.JWTFilter; +import com.fit2cloud.commons.auth.service.ShiroService; +import org.apache.shiro.mgt.DefaultSessionStorageEvaluator; +import org.apache.shiro.mgt.DefaultSubjectDAO; +import org.apache.shiro.spring.LifecycleBeanPostProcessor; +import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; +import org.apache.shiro.spring.web.ShiroFilterFactoryBean; +import org.apache.shiro.web.mgt.DefaultWebSecurityManager; +import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.DependsOn; +import javax.servlet.Filter; +import java.util.LinkedHashMap; +import java.util.Map; + +@Configuration +public class ShiroConfig { + + + @Bean("securityManager") + public DefaultWebSecurityManager getManager(F2cRealm f2cRealm) { + DefaultWebSecurityManager manager = new DefaultWebSecurityManager(); + // 使用自己的realm + manager.setRealm(f2cRealm); + + /* + * 关闭shiro自带的session,详情见文档 + * http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29 + */ + DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO(); + DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator(); + defaultSessionStorageEvaluator.setSessionStorageEnabled(false); + subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator); + manager.setSubjectDAO(subjectDAO); + + return manager; + } + + @Bean("shiroFilter") + public ShiroFilterFactoryBean factory(DefaultWebSecurityManager securityManager, ShiroService shiroService) { + ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); + // 添加自己的过滤器并且取名为jwt + Map filterMap = new LinkedHashMap<>(); + filterMap.put("f2cPerms", new F2CPermissionsFilter()); + //filterMap.put("f2cRoles", new F2CRolesFilter()); + filterMap.put("jwt", new JWTFilter()); + filterMap.put("logout", new F2CLogoutFilter()); + factoryBean.setFilters(filterMap); + factoryBean.setSecurityManager(securityManager); + factoryBean.setUnauthorizedUrl("/permissionMiss"); + factoryBean.setFilterChainDefinitionMap(shiroService.loadFilterChainDefinitionMap()); + return factoryBean; + } + + /** + * 下面的代码是添加注解支持 + */ + @Bean + @DependsOn("lifecycleBeanPostProcessor") + public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { + DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); + defaultAdvisorAutoProxyCreator.setProxyTargetClass(true); + return defaultAdvisorAutoProxyCreator; + } + + @Bean + public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { + return new LifecycleBeanPostProcessor(); + } + + @Bean + public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) { + AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); + advisor.setSecurityManager(securityManager); + return advisor; + } +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/dao/ExtUserMapper.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/dao/ExtUserMapper.java new file mode 100644 index 0000000000..0d9067f1d4 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/dao/ExtUserMapper.java @@ -0,0 +1,31 @@ +package com.fit2cloud.commons.auth.dao; + + +import com.fit2cloud.commons.auth.bean.ExtPermissionBean; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +@Mapper +public interface ExtUserMapper { + + @Select("select password from user where user_id = #{userId,jdbcType=VARCHAR} ") + String getPassword(String userId); + + @Select("select role_id from role_user where user_id = #{userId,jdbcType=VARCHAR} ") + List getRole(String userId); + + @Select({ + "select resource_id from permission p " , + "left join role_user ru on p.relation_id = ru.role_id " , + "where type = 'role' and ru.user_id = #{userId,jdbcType=VARCHAR} " + }) + List getPermission(String userId); + + @Select({ + "select p.*,r.url ", + "from permission p left join resource r on p.resource_id = r.id" + }) + List getPermissions(); +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/OrgUser.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/OrgUser.java new file mode 100644 index 0000000000..40b7b05163 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/OrgUser.java @@ -0,0 +1,44 @@ +package com.fit2cloud.commons.auth.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableField; +import java.io.Serializable; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * + *

+ * + * @author cyw + * @since 2021-02-03 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("org_user") +public class OrgUser implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId("id") + private String id; + + /** + * 部门ID + */ + @TableField("org_id") + private String orgId; + + /** + * 用户ID + */ + @TableField("user_id") + private String userId; + + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/Organization.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/Organization.java new file mode 100644 index 0000000000..9a884542d0 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/Organization.java @@ -0,0 +1,62 @@ +package com.fit2cloud.commons.auth.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableField; +import java.io.Serializable; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * + *

+ * + * @author cyw + * @since 2021-02-03 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("organization") +public class Organization implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId("id") + private String id; + + /** + * 部门名称 + */ + @TableField("name") + private String name; + + /** + * 描述 + */ + @TableField("description") + private String description; + + /** + * 上级部门ID + */ + @TableField("pid") + private Integer pid; + + /** + * 部门级别 + */ + @TableField("level") + private Integer level; + + /** + * 创建时间 + */ + @TableField("create_time") + private Long createTime; + + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/Permission.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/Permission.java new file mode 100644 index 0000000000..6844b5cfeb --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/Permission.java @@ -0,0 +1,50 @@ +package com.fit2cloud.commons.auth.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableField; +import java.io.Serializable; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * + *

+ * + * @author cyw + * @since 2021-02-03 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("permission") +public class Permission implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId("id") + private String id; + + /** + * 类型 + */ + @TableField("type") + private String type; + + /** + * 关联ID + */ + @TableField("relation_id") + private String relationId; + + /** + * 资源ID + */ + @TableField("resource_id") + private String resourceId; + + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/Resource.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/Resource.java new file mode 100644 index 0000000000..f4fcddca18 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/Resource.java @@ -0,0 +1,62 @@ +package com.fit2cloud.commons.auth.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableField; +import java.io.Serializable; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * + *

+ * + * @author cyw + * @since 2021-02-03 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("resource") +public class Resource implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId("id") + private String id; + + /** + * 资源名称 + */ + @TableField("name") + private String name; + + /** + * 资源描述 + */ + @TableField("desc") + private String desc; + + /** + * 资源类型 + */ + @TableField("type") + private String type; + + /** + * 资源地址 + */ + @TableField("url") + private String url; + + /** + * 创建时间 + */ + @TableField("create_time") + private Long createTime; + + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/Role.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/Role.java new file mode 100644 index 0000000000..5779f62d83 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/Role.java @@ -0,0 +1,50 @@ +package com.fit2cloud.commons.auth.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableField; +import java.io.Serializable; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * + *

+ * + * @author cyw + * @since 2021-02-03 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("role") +public class Role implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 角色ID + */ + @TableId("id") + private String id; + + /** + * 角色名称 + */ + @TableField("name") + private String name; + + /** + * 角色类型 + */ + @TableField("type") + private String type; + + /** + * 描述 + */ + @TableField("description") + private String description; + + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/RoleUser.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/RoleUser.java new file mode 100644 index 0000000000..19d54ecd54 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/RoleUser.java @@ -0,0 +1,44 @@ +package com.fit2cloud.commons.auth.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableField; +import java.io.Serializable; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * + *

+ * + * @author cyw + * @since 2021-02-03 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("role_user") +public class RoleUser implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId("id") + private String id; + + /** + * 角色ID + */ + @TableField("role_id") + private String roleId; + + /** + * 用户ID + */ + @TableField("user_id") + private String userId; + + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/User.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/User.java new file mode 100644 index 0000000000..9a15992eef --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/entity/User.java @@ -0,0 +1,68 @@ +package com.fit2cloud.commons.auth.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableField; +import java.io.Serializable; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *

+ * + *

+ * + * @author cyw + * @since 2021-02-03 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("user") +public class User implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId("user_id") + private String userId; + + /** + * 姓名 + */ + @TableField("user_name") + private String userName; + + /** + * 密码 + */ + @TableField("password") + private String password; + + /** + * 是否有效 + */ + @TableField("valid") + private Boolean valid; + + /** + * 电话号码 + */ + @TableField("phone_number") + private Integer phoneNumber; + + /** + * 邮箱 + */ + @TableField("email") + private String email; + + /** + * 创建时间 + */ + @TableField("create_time") + private Long createTime; + + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/filter/F2CLogoutFilter.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/filter/F2CLogoutFilter.java new file mode 100644 index 0000000000..433d8995ce --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/filter/F2CLogoutFilter.java @@ -0,0 +1,27 @@ +package com.fit2cloud.commons.auth.filter; + +import org.apache.shiro.subject.Subject; +import org.apache.shiro.web.filter.authc.LogoutFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +public class F2CLogoutFilter extends LogoutFilter { + + private static final Logger logger = LoggerFactory.getLogger(F2CLogoutFilter.class); + + + @Override + protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception { + Subject subject = getSubject(request, response); + try { + subject.logout(); + } catch (Exception ex) { + logger.error("退出登录错误",ex); + } + return true; + } + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/filter/F2CPermissionsFilter.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/filter/F2CPermissionsFilter.java new file mode 100644 index 0000000000..3877d5d68c --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/filter/F2CPermissionsFilter.java @@ -0,0 +1,30 @@ +package com.fit2cloud.commons.auth.filter; + +import org.apache.shiro.subject.Subject; +import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import java.io.IOException; + +public class F2CPermissionsFilter extends PermissionsAuthorizationFilter { + + @Override + public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException { + Subject subject = getSubject(request, response); + String[] perms = (String[]) mappedValue; + if (perms != null && perms.length > 0) { + for (String str : perms) { + // 判断访问的用户是否拥有mappedValue权限 + if (subject.isPermitted(str)) { + return true; + } + } + return false; + } + return true; + } + + + + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/filter/F2CRolesFilter.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/filter/F2CRolesFilter.java new file mode 100644 index 0000000000..6e8370d439 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/filter/F2CRolesFilter.java @@ -0,0 +1,25 @@ +package com.fit2cloud.commons.auth.filter; + +import org.apache.shiro.subject.Subject; +import org.apache.shiro.web.filter.authz.AuthorizationFilter; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +public class F2CRolesFilter extends AuthorizationFilter { + @Override + protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception { + Subject subject = getSubject(servletRequest, servletResponse); + String[] rolesArray = (String[]) o; + // 没有角色限制,有权限访问 + if (rolesArray == null || rolesArray.length == 0) { + return true; + } + for (int i = 0; i < rolesArray.length; i++) { + //若当前用户是rolesArray中的任何一个,则有权限访问 + if (subject.hasRole(rolesArray[i])) { + return true; + } + } + return false; + } +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/filter/JWTFilter.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/filter/JWTFilter.java new file mode 100644 index 0000000000..66c52e7528 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/filter/JWTFilter.java @@ -0,0 +1,121 @@ +package com.fit2cloud.commons.auth.filter; + +import com.fit2cloud.commons.auth.config.JWTToken; +import com.fit2cloud.commons.auth.util.JWTUtil; +import org.apache.shiro.subject.Subject; +import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.RequestMethod; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + + +public class JWTFilter extends BasicHttpAuthenticationFilter { + + + private Logger LOGGER = LoggerFactory.getLogger(this.getClass()); + + + /** + * 判断用户是否想要登入。 + * 检测header里面是否包含Authorization字段即可 + */ + @Override + protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) { + HttpServletRequest req = (HttpServletRequest) request; + String authorization = req.getHeader("Authorization"); + return authorization != null; + } + + /** + * + */ + @Override + protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception { + HttpServletRequest httpServletRequest = (HttpServletRequest) request; + String authorization = httpServletRequest.getHeader("Authorization"); + + if (JWTUtil.needRefresh(authorization)){ + authorization = refreshToken(request, response); + } + JWTToken token = new JWTToken(authorization); + Subject subject = getSubject(request, response); + // 提交给realm进行登入,如果错误他会抛出异常并被捕获 + subject.login(token); + return true; + } + + + + /** + */ + @Override + protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { + if (isLoginAttempt(request, response)) { + try { + boolean loginSuccess = executeLogin(request, response); + return loginSuccess; + } catch (Exception e) { + response401(request, response); + } + } + return false; + } + + private String refreshToken(ServletRequest request, ServletResponse response) { + // 获取AccessToken(Shiro中getAuthzHeader方法已经实现) + String token = this.getAuthzHeader(request); + // 获取当前Token的帐号信息 + String username = JWTUtil.getUsername(token); + String password = JWTUtil.getPassword(username); + try { + String newToken = JWTUtil.sign(username, password); + JWTToken jwtToken = new JWTToken(newToken); + this.getSubject(request, response).login(jwtToken); + // 设置响应的Header头新Token + HttpServletResponse httpServletResponse = (HttpServletResponse) response; + httpServletResponse.addHeader("Access-Control-Expose-Headers", "Authorization"); + httpServletResponse.setHeader("Authorization", newToken); + return newToken; + }catch (Exception e){ + e.printStackTrace(); + } + return null; + } + + + /** + * 对跨域提供支持 + */ + @Override + protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception { + HttpServletRequest httpServletRequest = (HttpServletRequest) request; + HttpServletResponse httpServletResponse = (HttpServletResponse) response; + httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin")); + httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE"); + httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers")); + // 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态 + if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) { + httpServletResponse.setStatus(HttpStatus.OK.value()); + return false; + } + return super.preHandle(request, response); + } + + /** + * 将非法请求跳转到 /401 + */ + private void response401(ServletRequest req, ServletResponse resp) { + try { + HttpServletResponse httpServletResponse = (HttpServletResponse) resp; + httpServletResponse.sendRedirect("/401"); + } catch (IOException e) { + LOGGER.error(e.getMessage()); + } + } +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/filter/XssFilter.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/filter/XssFilter.java new file mode 100644 index 0000000000..88050c84e0 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/filter/XssFilter.java @@ -0,0 +1,52 @@ +package com.fit2cloud.commons.auth.filter; + + +import cn.hutool.core.util.StrUtil; +import org.apache.commons.text.StringEscapeUtils; +import org.springframework.stereotype.Component; +import javax.servlet.*; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.IOException; + +@Component +@WebFilter +public class XssFilter implements Filter { + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { + XssHttpServletRequestWrapper xssHttpServletRequestWrapper = new XssHttpServletRequestWrapper((HttpServletRequest) request); + filterChain.doFilter(xssHttpServletRequestWrapper, response); + } + + @Override + public void destroy() { + + } + + class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { + + private HttpServletRequest request; + + public XssHttpServletRequestWrapper(HttpServletRequest request) { + super(request); + this.request = request; + } + + @Override + public String getParameter(String name) { + String oldValue = super.getParameter(name); + if(StrUtil.isEmpty(oldValue)){ + return oldValue; + } + String newValue = StringEscapeUtils.escapeHtml4(oldValue); + return newValue; + } + + } +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/OrgUserMapper.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/OrgUserMapper.java new file mode 100644 index 0000000000..c834dc5b12 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/OrgUserMapper.java @@ -0,0 +1,19 @@ +package com.fit2cloud.commons.auth.mapper; + +import com.fit2cloud.commons.auth.entity.OrgUser; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + + +/** + *

+ * Mapper 接口 + *

+ * + * @author cyw + * @since 2021-02-03 +*/ +@Mapper +public interface OrgUserMapper extends BaseMapper { + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/OrganizationMapper.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/OrganizationMapper.java new file mode 100644 index 0000000000..dbcc7fc88b --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/OrganizationMapper.java @@ -0,0 +1,19 @@ +package com.fit2cloud.commons.auth.mapper; + +import com.fit2cloud.commons.auth.entity.Organization; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + + +/** + *

+ * Mapper 接口 + *

+ * + * @author cyw + * @since 2021-02-03 +*/ +@Mapper +public interface OrganizationMapper extends BaseMapper { + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/PermissionMapper.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/PermissionMapper.java new file mode 100644 index 0000000000..3ae1ab84c9 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/PermissionMapper.java @@ -0,0 +1,19 @@ +package com.fit2cloud.commons.auth.mapper; + +import com.fit2cloud.commons.auth.entity.Permission; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + + +/** + *

+ * Mapper 接口 + *

+ * + * @author cyw + * @since 2021-02-03 +*/ +@Mapper +public interface PermissionMapper extends BaseMapper { + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/ResourceMapper.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/ResourceMapper.java new file mode 100644 index 0000000000..b37da8669b --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/ResourceMapper.java @@ -0,0 +1,19 @@ +package com.fit2cloud.commons.auth.mapper; + +import com.fit2cloud.commons.auth.entity.Resource; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + + +/** + *

+ * Mapper 接口 + *

+ * + * @author cyw + * @since 2021-02-03 +*/ +@Mapper +public interface ResourceMapper extends BaseMapper { + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/RoleMapper.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/RoleMapper.java new file mode 100644 index 0000000000..67daff2ba6 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/RoleMapper.java @@ -0,0 +1,19 @@ +package com.fit2cloud.commons.auth.mapper; + +import com.fit2cloud.commons.auth.entity.Role; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + + +/** + *

+ * Mapper 接口 + *

+ * + * @author cyw + * @since 2021-02-03 +*/ +@Mapper +public interface RoleMapper extends BaseMapper { + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/RoleUserMapper.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/RoleUserMapper.java new file mode 100644 index 0000000000..a5842631e7 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/RoleUserMapper.java @@ -0,0 +1,19 @@ +package com.fit2cloud.commons.auth.mapper; + +import com.fit2cloud.commons.auth.entity.RoleUser; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + + +/** + *

+ * Mapper 接口 + *

+ * + * @author cyw + * @since 2021-02-03 +*/ +@Mapper +public interface RoleUserMapper extends BaseMapper { + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/UserMapper.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/UserMapper.java new file mode 100644 index 0000000000..5b753afa9a --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/mapper/UserMapper.java @@ -0,0 +1,19 @@ +package com.fit2cloud.commons.auth.mapper; + +import com.fit2cloud.commons.auth.entity.User; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + + +/** + *

+ * Mapper 接口 + *

+ * + * @author cyw + * @since 2021-02-03 +*/ +@Mapper +public interface UserMapper extends BaseMapper { + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/service/ShiroService.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/service/ShiroService.java new file mode 100644 index 0000000000..bee83be7b0 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/service/ShiroService.java @@ -0,0 +1,36 @@ +package com.fit2cloud.commons.auth.service; + +import org.apache.shiro.spring.web.ShiroFilterFactoryBean; + +import java.util.Map; + +public interface ShiroService { + + /** + * 初始化权限 -> 拿全部权限 + * + * @param : + * @return: java.util.Map + */ + Map loadFilterChainDefinitionMap(); + + /** + * 在对uri权限进行增删改操作时,需要调用此方法进行动态刷新加载数据库中的uri权限 + * + * @param shiroFilterFactoryBean + * @param roleId + * @param isRemoveSession: + * @return: void + */ + void updatePermission(ShiroFilterFactoryBean shiroFilterFactoryBean, Integer roleId, Boolean isRemoveSession); + + /** + * shiro动态权限加载 -> 原理:删除shiro缓存,重新执行doGetAuthorizationInfo方法授权角色和权限 + * + * @param roleId + * @param isRemoveSession: + * @return: void + */ + void updatePermissionByRoleId(Integer roleId, Boolean isRemoveSession); + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/service/UserService.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/service/UserService.java new file mode 100644 index 0000000000..370ca39a78 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/service/UserService.java @@ -0,0 +1,40 @@ +package com.fit2cloud.commons.auth.service; + + +import cn.hutool.core.util.ObjectUtil; +import com.fit2cloud.commons.auth.bean.UserBean; +import com.fit2cloud.commons.auth.dao.ExtUserMapper; +import com.fit2cloud.commons.auth.entity.User; +import com.fit2cloud.commons.auth.mapper.UserMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import java.util.List; +import java.util.stream.Collectors; + +@Service +public class UserService { + + @Autowired(required = false) + private ExtUserMapper extUserMapper; + + @Autowired(required = false) + private UserMapper userMapper; + public UserBean getUser(String username){ + User user = userMapper.selectById(username); + if (ObjectUtil.isNull(user))return null; + String password = user.getPassword(); + List roles = extUserMapper.getRole(username); + String role = roles.stream().collect(Collectors.joining(",")); + List permissions = extUserMapper.getPermission(username); + String permission = permissions.stream().collect(Collectors.joining(",")); + UserBean userBean = UserBean.builder().username(username).password(password).role(role).permission(permission).build(); + return userBean; + } + + public String getPassword(String username){ + String password = extUserMapper.getPassword(username); + return password; + } + + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/service/impl/ShiroServiceImpl.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/service/impl/ShiroServiceImpl.java new file mode 100644 index 0000000000..f74113d33b --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/service/impl/ShiroServiceImpl.java @@ -0,0 +1,83 @@ +package com.fit2cloud.commons.auth.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.fit2cloud.commons.auth.dao.ExtUserMapper; +import com.fit2cloud.commons.auth.entity.Permission; +import com.fit2cloud.commons.auth.service.ShiroService; +import org.apache.shiro.spring.web.ShiroFilterFactoryBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import java.util.LinkedHashMap; +import java.util.Map; + +@Service +public class ShiroServiceImpl implements ShiroService { + + + @Autowired(required = false) + private ExtUserMapper extUserMapper; + + + @Override + public Map loadFilterChainDefinitionMap() { + // 权限控制map + Map filterChainDefinitionMap = new LinkedHashMap<>(); + // 配置过滤:不会被拦截的链接 -> 放行 start ---------------------------------------------------------- + // 放行Swagger2页面,需要放行这些 + + filterChainDefinitionMap.put("/swagger-ui.html","anon"); + filterChainDefinitionMap.put("/swagger/**","anon"); + filterChainDefinitionMap.put("/webjars/**", "anon"); + filterChainDefinitionMap.put("/swagger-resources/**","anon"); + filterChainDefinitionMap.put("/v2/**","anon"); + filterChainDefinitionMap.put("/static/**", "anon"); + + // 登陆 + filterChainDefinitionMap.put("/login", "anon"); + // 退出 + //filterChainDefinitionMap.put("/logout", "anon"); + // 放行未授权接口,重定向使用 + filterChainDefinitionMap.put("/unauth", "anon"); + // token过期接口 + filterChainDefinitionMap.put("/tokenExpired", "anon"); + // 被挤下线 + filterChainDefinitionMap.put("/downline", "anon"); + // 放行 end ---------------------------------------------------------- + filterChainDefinitionMap.put("/logout", "logout"); + //List resources = resourceMapper.selectList(null); + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq("type", "role"); + /*List extPermissionBeans = extUserMapper.getPermissions(); + + + if (CollectionUtils.isNotEmpty(extPermissionBeans)){ + Map> resourcePerMap = extPermissionBeans.stream().collect(Collectors.groupingBy(ExtPermissionBean::getKey)); + resourcePerMap.entrySet().stream().forEach(entry -> { + PermissionKey permissionKey = entry.getKey(); + String url = permissionKey.getUrl(); + String resourceId = permissionKey.getResourceId(); + //List permissionList = entry.getValue(); + //StringJoiner f2cRoles = new StringJoiner(",", "f2cRoles[", "]"); + StringJoiner f2cPerms = new StringJoiner(",", "f2cPerms[", "]"); + f2cPerms.add(resourceId); + *//*permissionList.forEach(per -> { + String roleId = per.getRelationId(); + f2cRoles.add(roleId); + });*//* + filterChainDefinitionMap.put(url, "jwt," + f2cPerms); + }); + }*/ + filterChainDefinitionMap.put("/**", "jwt"); + return filterChainDefinitionMap; + } + + @Override + public void updatePermission(ShiroFilterFactoryBean shiroFilterFactoryBean, Integer roleId, Boolean isRemoveSession) { + + } + + @Override + public void updatePermissionByRoleId(Integer roleId, Boolean isRemoveSession) { + + } +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/util/CacheUtil.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/util/CacheUtil.java new file mode 100644 index 0000000000..f6d34e076c --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/util/CacheUtil.java @@ -0,0 +1,55 @@ +package com.fit2cloud.commons.auth.util; + + +import cn.hutool.core.util.ObjectUtil; +import net.sf.ehcache.Cache; +import net.sf.ehcache.Element; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.CacheManager; +import org.springframework.cache.ehcache.EhCacheCacheManager; +import org.springframework.context.annotation.Configuration; + +/*@Configuration +public class CacheUtil { + private static CacheManager manager; + + @Autowired + public void setManager(CacheManager manager) { + CacheUtil.manager = manager; + } + + public static Object get(String cacheName, Object key) { + Cache cache = cache(cacheName); + if (ObjectUtil.isNull(cache))return null; + Element element = cache.get(key); + if (ObjectUtil.isNull(element))return null; + Object objectValue = element.getObjectValue(); + return objectValue; + } + + public static void put(String cacheName, Object key, Object value, Integer ttl, Integer tti) { + Element e = new Element(key, value); + //不设置则使用xml配置 + if (ttl != null) + e.setTimeToLive(ttl); + if (tti != null) + e.setTimeToIdle(tti); + cache(cacheName).put(e); + } + + public static boolean remove(String cacheName, Object key) { + return cache(cacheName).remove(key); + } + + public static void removeAll(String cacheName) { + cache(cacheName).removeAll(); + } + + private static Cache cache(String cacheName) { + net.sf.ehcache.CacheManager cacheManager = ((EhCacheCacheManager) manager).getCacheManager(); + if (!cacheManager.cacheExists(cacheName)) + cacheManager.addCache(cacheName); + Cache cache = cacheManager.getCache(cacheName); + return cache; + } +}*/ diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/util/JWTUtil.java b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/util/JWTUtil.java new file mode 100644 index 0000000000..7080f406f3 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/java/com/fit2cloud/commons/auth/util/JWTUtil.java @@ -0,0 +1,101 @@ +package com.fit2cloud.commons.auth.util; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.exceptions.JWTDecodeException; +import com.auth0.jwt.interfaces.DecodedJWT; +import com.fit2cloud.commons.auth.dao.ExtUserMapper; +import com.fit2cloud.commons.auth.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; + +import java.util.Date; + + +@Component +public class JWTUtil { + + // 过期时间5分钟 + private static final long EXPIRE_TIME = 5*60*1000; + + + private static ExtUserMapper extUserMapper; + + + @Autowired + public void setExtUserMapper(ExtUserMapper extUserMapper) { + JWTUtil.extUserMapper = extUserMapper; + } + + /** + * 校验token是否正确 + * @param token 密钥 + * @param secret 用户的密码 + * @return 是否正确 + */ + public static boolean verify(String token, String username, String secret) { + Algorithm algorithm = Algorithm.HMAC256(secret); + JWTVerifier verifier = JWT.require(algorithm) + .withClaim("username", username) + .build(); + verifier.verify(token); + return true; + } + + /** + * 获得token中的信息无需secret解密也能获得 + * @return token中包含的用户名 + */ + public static String getUsername(String token) { + try { + DecodedJWT jwt = JWT.decode(token); + return jwt.getClaim("username").asString(); + } catch (JWTDecodeException e) { + return null; + } + } + + public static String getPassword(String username){ + String password = extUserMapper.getPassword(username); + return password; + } + + public static boolean needRefresh(String token){ + Date exp = JWTUtil.getExp(token); + return new Date().getTime() >= exp.getTime(); + } + + public static Date getExp(String token) { + try { + DecodedJWT jwt = JWT.decode(token); + return jwt.getClaim("exp").asDate(); + } catch (JWTDecodeException e) { + return null; + } + } + + /** + * 生成签名,5min后过期 + * @param username 用户名 + * @param secret 用户的密码 + * @return 加密的token + */ + public static String sign(String username, String secret) { + try { + Date date = new Date(System.currentTimeMillis()+EXPIRE_TIME); + Algorithm algorithm = Algorithm.HMAC256(secret); + // 附带username信息 + return JWT.create() + .withClaim("username", username) + .withClaim("exp", date) + .withExpiresAt(date) + .sign(algorithm); + } catch (Exception e) { + return null; + } + } + + +} diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/resources/application.properties b/fit2cloud-commons/fit2cloud-common-auth/src/main/resources/application.properties new file mode 100644 index 0000000000..f6aa23d3e1 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/resources/application.properties @@ -0,0 +1,2 @@ +spring.cache.type=ehcache +spring.cache.ehcache.config=ehcache.xml \ No newline at end of file diff --git a/fit2cloud-commons/fit2cloud-common-auth/src/main/resources/ehcache.xml b/fit2cloud-commons/fit2cloud-common-auth/src/main/resources/ehcache.xml new file mode 100644 index 0000000000..cddcab2849 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-auth/src/main/resources/ehcache.xml @@ -0,0 +1,24 @@ + + + + + + + + \ No newline at end of file diff --git a/fit2cloud-commons/fit2cloud-common-base/pom.xml b/fit2cloud-commons/fit2cloud-common-base/pom.xml new file mode 100644 index 0000000000..fa5c7e07ce --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-base/pom.xml @@ -0,0 +1,15 @@ + + + + fit2cloud-commons + com.fit2cloud + 1.0-SNAPSHOT + + 4.0.0 + + fit2cloud-common-base + + + \ No newline at end of file diff --git a/fit2cloud-commons/fit2cloud-common-base/src/main/java/com/fit2cloud/commons/base/Fit2cloudException.java b/fit2cloud-commons/fit2cloud-common-base/src/main/java/com/fit2cloud/commons/base/Fit2cloudException.java new file mode 100644 index 0000000000..52ec220288 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-base/src/main/java/com/fit2cloud/commons/base/Fit2cloudException.java @@ -0,0 +1,71 @@ +package com.fit2cloud.commons.base; + +import cn.hutool.core.util.StrUtil; +import com.fit2cloud.commons.base.result.ResultEntity; +import org.slf4j.LoggerFactory; +import org.springframework.boot.web.error.ErrorAttributeOptions; +import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.web.servlet.error.ErrorController; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.context.request.*; +import javax.annotation.Resource; +import javax.servlet.RequestDispatcher; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + + +@RestController +public class Fit2cloudException extends ResultEntity implements ErrorController { + public static final org.slf4j.Logger Logger = LoggerFactory.getLogger(Fit2cloudException.class); + private static final String PATH = "/error"; + + + @Resource + private ErrorAttributes errorAttributes; + @Override + public String getErrorPath() { + return PATH; + } + + @RequestMapping(PATH) + public ResultEntity error(){ + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); + ServletRequestAttributes attributes = (ServletRequestAttributes) requestAttributes; + HttpServletRequest request = attributes.getRequest(); + HttpServletResponse response = attributes.getResponse(); + WebRequest webRequest = new ServletWebRequest(request); + ErrorAttributeOptions.Include[] values = ErrorAttributeOptions.Include.values(); + List collect = Stream.of(values).collect(Collectors.toList()); + ErrorAttributeOptions options = ErrorAttributeOptions.of(collect); + Map errorAttributeMap = this.errorAttributes.getErrorAttributes(webRequest, options); + Throwable t = errorAttributes.getError(webRequest); + Integer code = (Integer) errorAttributeMap.get("status"); + response.setStatus(code); + String errorMessage = StrUtil.EMPTY; + if (t != null) { + if (Logger.isDebugEnabled()) { + Logger.error("Fail to proceed " + errorAttributeMap.get("path"), t); + } + errorMessage = t.getMessage(); + } + if (StrUtil.isBlank(errorMessage)) { + if (code == 403) { + errorMessage = "Permission Denied."; + } else if (code == 404) { + String path = request.getServletPath(); + if(Objects.nonNull(request.getAttribute(RequestDispatcher.ERROR_REQUEST_URI)) && StrUtil.isNotBlank(request.getAttribute(RequestDispatcher.ERROR_REQUEST_URI).toString())){ + path = request.getAttribute(RequestDispatcher.ERROR_REQUEST_URI).toString(); + } + errorMessage = path + " not found."; + } else { + errorMessage = "The server responds " + code + " but no detailed message."; + } + } + return error(errorMessage); + + } +} diff --git a/fit2cloud-commons/fit2cloud-common-base/src/main/java/com/fit2cloud/commons/base/Fit2cloudResult.java b/fit2cloud-commons/fit2cloud-common-base/src/main/java/com/fit2cloud/commons/base/Fit2cloudResult.java new file mode 100644 index 0000000000..09f23d45bf --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-base/src/main/java/com/fit2cloud/commons/base/Fit2cloudResult.java @@ -0,0 +1,38 @@ +package com.fit2cloud.commons.base; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.fit2cloud.commons.base.result.ResultEntity; +import org.springframework.core.MethodParameter; +import org.springframework.http.MediaType; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.http.server.ServerHttpRequest; +import org.springframework.http.server.ServerHttpResponse; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; + +@RestControllerAdvice({"com.fit2cloud", "springfox.documentation.swagger2.web"}) +public class Fit2cloudResult extends ResultEntity implements ResponseBodyAdvice { + @Override + public boolean supports(MethodParameter methodParameter, Class converterType) { + return MappingJackson2HttpMessageConverter.class.isAssignableFrom(converterType) || StringHttpMessageConverter.class.isAssignableFrom(converterType); + } + + @Override + public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class converterType, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { + String path = serverHttpRequest.getURI().getPath(); + + if (StrUtil.equalsIgnoreCase(path, "/v2/api-docs")) { + return o; + } + + if (!(o instanceof ResultEntity)) { + if (o instanceof String){ + return JSONUtil.toJsonStr(success(o)); + } + return success(o); + } + return o; + } +} diff --git a/fit2cloud-commons/fit2cloud-common-base/src/main/java/com/fit2cloud/commons/base/api/PermissionErrorApi.java b/fit2cloud-commons/fit2cloud-common-base/src/main/java/com/fit2cloud/commons/base/api/PermissionErrorApi.java new file mode 100644 index 0000000000..33e39e5577 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-base/src/main/java/com/fit2cloud/commons/base/api/PermissionErrorApi.java @@ -0,0 +1,13 @@ +package com.fit2cloud.commons.base.api; + +import com.fit2cloud.commons.base.result.ResultEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PermissionErrorApi extends ResultEntity { + @GetMapping("/permissionMiss") + public ResultEntity error(){ + return permission(); + } +} diff --git a/fit2cloud-commons/fit2cloud-common-base/src/main/java/com/fit2cloud/commons/base/api/TokenExpApi.java b/fit2cloud-commons/fit2cloud-common-base/src/main/java/com/fit2cloud/commons/base/api/TokenExpApi.java new file mode 100644 index 0000000000..2391764315 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-base/src/main/java/com/fit2cloud/commons/base/api/TokenExpApi.java @@ -0,0 +1,14 @@ +package com.fit2cloud.commons.base.api; + +import com.fit2cloud.commons.base.result.ResultEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class TokenExpApi extends ResultEntity { + + @GetMapping("/tokenExp") + public ResultEntity tokenExp(){ + return tokenExp(); + } +} diff --git a/fit2cloud-commons/fit2cloud-common-base/src/main/java/com/fit2cloud/commons/base/result/ResultCode.java b/fit2cloud-commons/fit2cloud-common-base/src/main/java/com/fit2cloud/commons/base/result/ResultCode.java new file mode 100644 index 0000000000..435778b983 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-base/src/main/java/com/fit2cloud/commons/base/result/ResultCode.java @@ -0,0 +1,40 @@ +package com.fit2cloud.commons.base.result; + + +import lombok.Data; + + +public enum ResultCode { + + OK(null, 20000),TOKENIll("Illegal token", 50008), + RELOG("Other clients logged in", 50012),TOKENEXP("Token expired", 50014),NOPERMISSION("No permission!", 50016); + + private String message; + + private int value; + + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } + + ResultCode() { + } + + ResultCode(String message, int value) { + this.message = message; + this.value = value; + } +} diff --git a/fit2cloud-commons/fit2cloud-common-base/src/main/java/com/fit2cloud/commons/base/result/ResultEntity.java b/fit2cloud-commons/fit2cloud-common-base/src/main/java/com/fit2cloud/commons/base/result/ResultEntity.java new file mode 100644 index 0000000000..bc392cf4f1 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-base/src/main/java/com/fit2cloud/commons/base/result/ResultEntity.java @@ -0,0 +1,58 @@ +package com.fit2cloud.commons.base.result; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ResultEntity implements Serializable { + + private String message; + + private boolean success; + + private int code; + + private Object data; + + public ResultEntity success(){ + this.code = ResultCode.OK.getValue(); + this.success = true; + return this; + } + public ResultEntity success(Object o){ + this.code = ResultCode.OK.getValue(); + this.success = true; + this.data = o; + return this; + } + public ResultEntity error(){ + this.code = 500; + this.success = false; + return this; + } + public ResultEntity error(String msg){ + this.code = 500; + this.success = false; + this.message = msg; + return this; + } + public ResultEntity permission(){ + this.code = ResultCode.NOPERMISSION.getValue(); + this.success = false; + this.message = ResultCode.NOPERMISSION.getMessage(); + return this; + } + + public ResultEntity tokenExp(){ + this.code = ResultCode.TOKENEXP.getValue(); + this.success = false; + this.message = ResultCode.TOKENEXP.getMessage(); + return this; + } + +} diff --git a/fit2cloud-commons/fit2cloud-common-db/pom.xml b/fit2cloud-commons/fit2cloud-common-db/pom.xml new file mode 100644 index 0000000000..994fb2e30d --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-db/pom.xml @@ -0,0 +1,64 @@ + + + + fit2cloud-commons + com.fit2cloud + 1.0-SNAPSHOT + + 4.0.0 + + fit2cloud-common-db + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + ${mybatis-starter.version} + + + + mysql + mysql-connector-java + runtime + + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + + com.baomidou + mybatis-plus-generator + ${mybatis-plus.version} + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + org.flywaydb + flyway-core + ${flyway.version} + + + + com.github.pagehelper + pagehelper-spring-boot-starter + ${pagehelper.version} + + + + org.freemarker + freemarker + 2.3.30 + + + + + \ No newline at end of file diff --git a/fit2cloud-commons/fit2cloud-common-db/src/main/java/com/fit2cloud/common/db/CodeGenerator.java b/fit2cloud-commons/fit2cloud-common-db/src/main/java/com/fit2cloud/common/db/CodeGenerator.java new file mode 100644 index 0000000000..7baa1bd59d --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-db/src/main/java/com/fit2cloud/common/db/CodeGenerator.java @@ -0,0 +1,117 @@ +package com.fit2cloud.common.db; + + +import com.baomidou.mybatisplus.generator.AutoGenerator; +import com.baomidou.mybatisplus.generator.InjectionConfig; +import com.baomidou.mybatisplus.generator.config.*; +import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert; +import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; +import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Service; +import java.util.ArrayList; +import java.util.List; + +@Service +public class CodeGenerator { + + + /*private static String scanner(String tip) { + Scanner scanner = new Scanner(System.in); + StringBuilder help = new StringBuilder(); + help.append("请输入" + tip + ":"); + System.out.println(help.toString()); + if (scanner.hasNext()) { + String ipt = scanner.next(); + if (StrUtil.isNotBlank(ipt)) { + return ipt; + } + } + throw new MybatisPlusException("请输入正确的" + tip + "!"); + }*/ + + + @Autowired + private Environment environment; + public void generator(String moduleName,String basePackage ,String tableName) { + + // 代码生成器 + AutoGenerator mpg = new AutoGenerator(); + // 全局配置 + GlobalConfig gc = new GlobalConfig(); + String projectPath = System.getProperty("user.dir")+"/"+moduleName; + //System.out.println(projectPath); + gc.setOutputDir(projectPath + "/src/main/java"); + gc.setAuthor("cyw"); + gc.setOpen(false); + // gc.setSwagger2(true); 实体属性 Swagger2 注解 + mpg.setGlobalConfig(gc); + // 数据源配置 + DataSourceConfig dsc = new DataSourceConfig(); + /*dsc.setUrl("jdbc:mysql://106.15.239.57:3306/data_ease?autoReconnect=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false"); + dsc.setDriverName("com.mysql.jdbc.Driver"); + dsc.setUsername("root"); + dsc.setPassword("Password123@mysql");*/ + dsc.setUrl(environment.getProperty("spring.datasource.url")); + dsc.setDriverName(environment.getProperty("spring.datasource.driver-class-name")); + dsc.setUsername(environment.getProperty("spring.datasource.username")); + dsc.setPassword(environment.getProperty("spring.datasource.password")); + dsc.setTypeConvert(new MySqlTypeConvert()); + mpg.setDataSource(dsc); + + // 包配置 + PackageConfig pc = new PackageConfig(); + /*pc.setModuleName(scanner("模块名"));*/ + pc.setModuleName(basePackage); + pc.setParent("com.fit2cloud"); + pc.setEntity("entity"); + pc.setMapper("mapper"); + mpg.setPackageInfo(pc); + + // 自定义配置 + InjectionConfig cfg = new InjectionConfig() { + @Override + public void initMap() { + // to do nothing + } + }; + + // 如果模板引擎是 freemarker + String templatePath = "f2cmapper.java"; + + // 自定义输出配置 + List focList = new ArrayList<>(); + + cfg.setFileOutConfigList(focList); + mpg.setCfg(cfg); + + // 配置模板 + TemplateConfig templateConfig = new TemplateConfig(); + templateConfig.setMapper(templatePath); + templateConfig.setService(null); + templateConfig.setServiceImpl(null); + templateConfig.setController(null); + templateConfig.setXml(null); + + + mpg.setTemplate(templateConfig); + + // 策略配置 + StrategyConfig strategy = new StrategyConfig(); + + strategy.setNaming(NamingStrategy.underline_to_camel); + strategy.setColumnNaming(NamingStrategy.underline_to_camel); + + strategy.setEntityLombokModel(true); + /*strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));*/ + strategy.setInclude(tableName.split(",")); + strategy.setControllerMappingHyphenStyle(true); + strategy.setTablePrefix(pc.getModuleName() + "_"); + strategy.setEntityTableFieldAnnotationEnable(true); + strategy.setSkipView(true); + mpg.setStrategy(strategy); + mpg.setTemplateEngine(new FreemarkerTemplateEngine()); + mpg.execute(); + } +} diff --git a/fit2cloud-commons/fit2cloud-common-db/src/main/java/com/fit2cloud/common/db/GeneratorApi.java b/fit2cloud-commons/fit2cloud-common-db/src/main/java/com/fit2cloud/common/db/GeneratorApi.java new file mode 100644 index 0000000000..e712abf035 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-db/src/main/java/com/fit2cloud/common/db/GeneratorApi.java @@ -0,0 +1,17 @@ +package com.fit2cloud.common.db; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class GeneratorApi { + + @Autowired + private CodeGenerator codeGenerator; + @GetMapping("/generator/{moduleName}/{basePackage}/{tableName}") + public void generator(@PathVariable("moduleName") String moduleName, @PathVariable("basePackage") String basePackage, @PathVariable("tableName") String tableName){ + codeGenerator.generator(moduleName, basePackage, tableName); + } +} diff --git a/fit2cloud-commons/fit2cloud-common-db/src/main/java/com/fit2cloud/common/db/MybatisPlusConfig.java b/fit2cloud-commons/fit2cloud-common-db/src/main/java/com/fit2cloud/common/db/MybatisPlusConfig.java new file mode 100644 index 0000000000..f8e1594e38 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-db/src/main/java/com/fit2cloud/common/db/MybatisPlusConfig.java @@ -0,0 +1,29 @@ +package com.fit2cloud.common.db; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class MybatisPlusConfig { + + + + /** + * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题 + */ + /*@Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); + return interceptor; + } + + @Bean + public ConfigurationCustomizer configurationCustomizer() { + return configuration -> configuration.setUseDeprecatedExecutor(false); + }*/ +} diff --git a/fit2cloud-commons/fit2cloud-common-db/src/main/java/com/fit2cloud/common/db/PageUtils.java b/fit2cloud-commons/fit2cloud-common-db/src/main/java/com/fit2cloud/common/db/PageUtils.java new file mode 100644 index 0000000000..e62b08fc43 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-db/src/main/java/com/fit2cloud/common/db/PageUtils.java @@ -0,0 +1,18 @@ +package com.fit2cloud.common.db; + +import com.github.pagehelper.Page; + +public class PageUtils { + public static Pager setPageInfo(Page page, T obj) { + try { + Pager pager = new Pager<>(); + pager.setListObject(obj); + pager.setPageCount(page.getPages()); + pager.setItemCount(page.getTotal()); + return pager; + } catch (Exception e) { + //LogUtil.error("Error saving current page number data:", e); + throw new RuntimeException("Error saving current page number data!"); + } + } +} diff --git a/fit2cloud-commons/fit2cloud-common-db/src/main/java/com/fit2cloud/common/db/Pager.java b/fit2cloud-commons/fit2cloud-common-db/src/main/java/com/fit2cloud/common/db/Pager.java new file mode 100644 index 0000000000..3daf57e250 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-db/src/main/java/com/fit2cloud/common/db/Pager.java @@ -0,0 +1,19 @@ +package com.fit2cloud.common.db; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Pager { + + private T listObject; + + private long itemCount; + + private long pageCount; + + +} diff --git a/fit2cloud-commons/fit2cloud-common-db/src/main/resources/application.properties b/fit2cloud-commons/fit2cloud-common-db/src/main/resources/application.properties new file mode 100644 index 0000000000..36605ed7c4 --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-db/src/main/resources/application.properties @@ -0,0 +1,6 @@ +spring.flyway.enabled=true +spring.flyway.baseline-on-migrate=true +spring.flyway.table=f2c_version +spring.flyway.baseline-version=0 +spring.flyway.encoding=UTF-8 +spring.flyway.validate-on-migrate=false \ No newline at end of file diff --git a/fit2cloud-commons/fit2cloud-common-db/src/main/resources/f2cmapper.java.ftl b/fit2cloud-commons/fit2cloud-common-db/src/main/resources/f2cmapper.java.ftl new file mode 100644 index 0000000000..37e910967a --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-db/src/main/resources/f2cmapper.java.ftl @@ -0,0 +1,27 @@ +package ${package.Mapper}; + +import ${package.Entity}.${entity}; +import ${superMapperClassPackage}; +<#if table.convert> +import org.apache.ibatis.annotations.Mapper; + + + +/** + *

+ * ${table.comment!} Mapper 接口 + *

+ * + * @author ${author} + * @since ${date} +*/ +<#if kotlin> +interface ${table.mapperName} : ${superMapperClass}<${entity}> +<#else> +<#if table.convert> +@Mapper + +public interface ${table.mapperName} extends ${superMapperClass}<${entity}> { + +} + diff --git a/fit2cloud-commons/fit2cloud-common-logs/pom.xml b/fit2cloud-commons/fit2cloud-common-logs/pom.xml new file mode 100644 index 0000000000..213646cded --- /dev/null +++ b/fit2cloud-commons/fit2cloud-common-logs/pom.xml @@ -0,0 +1,15 @@ + + + + fit2cloud-commons + com.fit2cloud + 1.0-SNAPSHOT + + 4.0.0 + + fit2cloud-common-logs + + + \ No newline at end of file diff --git a/fit2cloud-commons/pom.xml b/fit2cloud-commons/pom.xml new file mode 100644 index 0000000000..1546c4ddb2 --- /dev/null +++ b/fit2cloud-commons/pom.xml @@ -0,0 +1,22 @@ + + + + fit2cloud-frame + com.fit2cloud + 1.0-SNAPSHOT + + 4.0.0 + + fit2cloud-commons + pom + + fit2cloud-common-auth + fit2cloud-common-base + fit2cloud-common-logs + fit2cloud-common-db + + + + \ No newline at end of file diff --git a/fit2cloud-system/pom.xml b/fit2cloud-system/pom.xml new file mode 100644 index 0000000000..638564908d --- /dev/null +++ b/fit2cloud-system/pom.xml @@ -0,0 +1,50 @@ + + + + fit2cloud-frame + com.fit2cloud + 1.0-SNAPSHOT + + 4.0.0 + + fit2cloud-system + + + + + + com.fit2cloud + fit2cloud-common-base + 1.0-SNAPSHOT + + + + com.fit2cloud + fit2cloud-common-auth + 1.0-SNAPSHOT + + + + com.fit2cloud + fit2cloud-common-db + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-test + + + + + + + + + \ No newline at end of file diff --git a/fit2cloud-system/src/main/java/com/fit2cloud/SystemApp.java b/fit2cloud-system/src/main/java/com/fit2cloud/SystemApp.java new file mode 100644 index 0000000000..b893cc534e --- /dev/null +++ b/fit2cloud-system/src/main/java/com/fit2cloud/SystemApp.java @@ -0,0 +1,18 @@ +package com.fit2cloud; + + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cache.annotation.EnableCaching; + + +@EnableCaching +@SpringBootApplication +public class SystemApp { + + public static void main(String[] args) { + SpringApplication.run(SystemApp.class); + } + + +} diff --git a/fit2cloud-system/src/main/java/com/fit2cloud/system/api/BusiApi.java b/fit2cloud-system/src/main/java/com/fit2cloud/system/api/BusiApi.java new file mode 100644 index 0000000000..8b2108df62 --- /dev/null +++ b/fit2cloud-system/src/main/java/com/fit2cloud/system/api/BusiApi.java @@ -0,0 +1,37 @@ +package com.fit2cloud.system.api; + + +import com.fit2cloud.common.db.PageUtils; +import com.fit2cloud.common.db.Pager; +import com.fit2cloud.commons.auth.entity.User; +import com.fit2cloud.commons.auth.mapper.UserMapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +public class BusiApi { + + @GetMapping("/busi/dashboard") + public Object dashboard(){ + return "dashboard"; + } + + + @Autowired + private UserMapper userMapper; + + @GetMapping("/page") + public Object list(){ + int startpage = 1; + int limit = 10; + Page page = PageHelper.startPage(startpage, limit); + List users = userMapper.selectList(null); + Pager> pageInfo = PageUtils.setPageInfo(page, users); + return pageInfo; + } +} diff --git a/fit2cloud-system/src/main/java/com/fit2cloud/system/api/SysApi.java b/fit2cloud-system/src/main/java/com/fit2cloud/system/api/SysApi.java new file mode 100644 index 0000000000..d143c689bb --- /dev/null +++ b/fit2cloud-system/src/main/java/com/fit2cloud/system/api/SysApi.java @@ -0,0 +1,15 @@ +package com.fit2cloud.system.api; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + + +@RestController +public class SysApi { + + + @GetMapping("/sys/manager") + public Object manager(){ + return "manager"; + } +} diff --git a/fit2cloud-system/src/main/java/com/fit2cloud/system/api/TestApi.java b/fit2cloud-system/src/main/java/com/fit2cloud/system/api/TestApi.java new file mode 100644 index 0000000000..dfc59b6df8 --- /dev/null +++ b/fit2cloud-system/src/main/java/com/fit2cloud/system/api/TestApi.java @@ -0,0 +1,54 @@ +package com.fit2cloud.system.api; + + + + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import java.util.HashMap; +import java.util.Map; + +@RestController +public class TestApi { + + + + @GetMapping("/test") + public Object test(){ + return "apple"; + } + + @GetMapping("/test1") + public Map test1(){ + + Map map = new HashMap(); + map.put("1", "a"); + map.put("2", "b"); + return map; + } + + @RequiresPermissions("") + @GetMapping("/test2") + public Map test2(){ + + //Map map = new HashMap(); + Map map = null; + + try { + map.put("1", "a"); + map.put("2", "b"); + }catch (Exception e){ + e.printStackTrace(); + } + + return map; + } + + + + + + + +} diff --git a/fit2cloud-system/src/main/resources/application.properties b/fit2cloud-system/src/main/resources/application.properties new file mode 100644 index 0000000000..71c0a89eb5 --- /dev/null +++ b/fit2cloud-system/src/main/resources/application.properties @@ -0,0 +1,6 @@ +spring.datasource.type=com.alibaba.druid.pool.DruidDataSource +spring.datasource.url=jdbc:mysql://106.15.239.57:3306/data_ease?autoReconnect=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false +spring.datasource.username=root +spring.datasource.password=Password123@mysql +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +mybatis.mapper-locations=classpath:mapper/*.xml \ No newline at end of file diff --git a/fit2cloud-system/src/main/resources/db/migration/V1__init.sql b/fit2cloud-system/src/main/resources/db/migration/V1__init.sql new file mode 100644 index 0000000000..4612340584 --- /dev/null +++ b/fit2cloud-system/src/main/resources/db/migration/V1__init.sql @@ -0,0 +1,8 @@ +CREATE TABLE test_users ( + id bigint(20) NOT NULL AUTO_INCREMENT, + username varchar(100) NOT NULL, + first_name varchar(50) NOT NULL, + last_name varchar(50) DEFAULT NULL, + PRIMARY KEY (id), + UNIQUE KEY UK_username (username) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/fit2cloud-system/src/test/java/com/fit2cloud/MyTest.java b/fit2cloud-system/src/test/java/com/fit2cloud/MyTest.java new file mode 100644 index 0000000000..0e27cf82c0 --- /dev/null +++ b/fit2cloud-system/src/test/java/com/fit2cloud/MyTest.java @@ -0,0 +1,23 @@ +package com.fit2cloud; + +import com.fit2cloud.common.db.CodeGenerator; +import lombok.SneakyThrows; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +public class MyTest { + + /*public static void main(String[] args) throws IOException { + ClassLoader classLoader = SystemApp.class.getClassLoader(); + InputStream resourceAsStream = classLoader.getResourceAsStream("application.properties"); + Properties properties = new Properties(); + properties.load(resourceAsStream); + System.setProperties(properties); + + CodeGenerator.test(); + }*/ + +} diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000000..0795d4762b --- /dev/null +++ b/pom.xml @@ -0,0 +1,148 @@ + + + 4.0.0 + + com.fit2cloud + fit2cloud-frame + 1.0-SNAPSHOT + + fit2cloud-commons + fit2cloud-system + + pom + + + org.springframework.boot + spring-boot-starter-parent + 2.4.2 + + + + + UTF-8 + UTF-8 + 2.0.0 + 1.4.0 + 3.12.1 + 2.1.3 + 3.4.1 + 1.3.7 + 1.3.0 + 7.5.2 + 1.2.4 + 2.6.9 + 2.9.0 + 2.0.5 + 1.8 + + + 5.5.8 + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-web + + + org.projectlombok + lombok + + + + cn.hutool + hutool-all + ${hutool.version} + + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12.4 + + true + + + + maven-source-plugin + 3.0.0 + + true + + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + + + + jcenter-snapshots + jcenter + https://jcenter.bintray.com/ + + + releases + Nexus Release Repository + http://repository.fit2cloud.com/content/repositories/releases/ + + + fit2cloud-enterprise-release + Fit2Cloud Enterprise Release + http://repository.fit2cloud.com/content/repositories/fit2cloud-enterprise-release/ + + + fit2cloud + fit2cloud + http://repository.fit2cloud.com/content/groups/public/ + + + fit2cloud-public + fit2cloud-public + http://repository.fit2cloud.com/content/repositories/fit2cloud-public + + + + + + releases + Nexus Release Repository + http://repository.fit2cloud.com/content/repositories/releases/ + + + snapshots + Nexus Snapshot Repository + http://repository.fit2cloud.com/content/repositories/snapshots/ + + + + + \ No newline at end of file