update 2021年11月4日18:33:20

master
zhangmeng 2021-11-05 18:36:40 +08:00
parent c5125175d9
commit f4499162c0
12 changed files with 197 additions and 108 deletions

View File

@ -1,21 +1,36 @@
package com.zhangmeng.admin.manager.controller;
import com.zhangmeng.admin.manager.service.PermissionService;
import com.zhangmeng.admin.manager.utils.UserUtil;
import com.zhangmeng.model.base.baseController.BaseController;
import com.zhangmeng.model.dto.Menu;
import com.zhangmeng.model.entity.Permission;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
import java.util.UUID;
/**
*
*
* @author zhangmeng
* @date 202111414:18:48
* @version 1.0
* @date 202111414:18:48
*/
@Controller
public class RequestController extends BaseController {
@Autowired
private UserUtil userUtil;
@Autowired
private PermissionService permissionService;
//登录
@RequestMapping("/login")
public ModelAndView login() {
@ -24,7 +39,16 @@ public class RequestController extends BaseController {
//首页
@RequestMapping("/admin/index")
public ModelAndView index (){
public ModelAndView index(Model model) {
String uuid = UUID.randomUUID().toString();
model.addAttribute("uuid", uuid);
model.addAttribute("loginUser", this.userUtil.currentUser());
return this.jumpPage("admin/index");
}
@GetMapping("/user/menuList")
public List<Menu> permissionList() {
List<Permission> permissions = this.permissionService.findByUserId(this.userUtil.currentUser().getId());
return this.permissionService.toUserMenus(permissions, 0L);
}
}

View File

@ -0,0 +1,27 @@
package com.zhangmeng.admin.manager.utils;
import com.zhangmeng.model.bean.TokenTools;
import com.zhangmeng.model.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.zhangmeng.admin.manager.service.UserService;
import java.util.Map;
@Component
public class UserUtil {
@Autowired
private TokenTools tokenTools;
@Autowired
private UserService userService;
public User currentUser() {
Map<String, Object> userInfo = this.tokenTools.getUserInfo();
return this.userService.loadUserByUsername(userInfo.get("username").toString());
}
public Map<String,Object> claims(){
return this.tokenTools.getUserInfo();
}
}

View File

@ -3,6 +3,7 @@ function postToPage(url, token) {
f.style.display = 'none';
f.action = url;
f.method = 'post';
f.enctype ='application/x-www-form-urlencoded';
f.innerHTML = '<input type="hidden" name="Authorization" value="' + token + '"/>';
document.body.appendChild(f);
f.submit();

View File

@ -59,7 +59,7 @@ layui.define(['table', 'jquery', 'element'], function(exports) {
menuTitle: dom.attr("menu-title"),
menuPath: dom.attr("menu-title"),
menuIcon: dom.attr("menu-icon"),
menuUrl: dom.attr("menu-url") + "?token=" + localStorage.getItem("token"),
menuUrl: dom.attr("menu-url") + "?Authorization=" + localStorage.getItem("Authorization"),
openType: dom.attr("open-type")
};
var doms = hash(dom);
@ -164,7 +164,8 @@ layui.define(['table', 'jquery', 'element'], function(exports) {
function getData(url) {
var defer = $.Deferred();
$.get(url + "?token="+localStorage.getItem("token")+"&fresh=" + Math.random(), function(result) {
$.setRequestHeader('Authorization',localStorage.getItem("Authorization"));
$.get(url + "?access_token="+localStorage.getItem("Authorization")+"&fresh=" + Math.random(), function(result) {
defer.resolve(result)
});
return defer.promise();
@ -172,9 +173,9 @@ layui.define(['table', 'jquery', 'element'], function(exports) {
function postData(url) {
var defer = $.Deferred();
$.post(url + "?token="+localStorage.getItem("token")+"&fresh=" + Math.random(), function(result) {
$.post(url + "?access_token="+localStorage.getItem("Authorization")+"&fresh=" + Math.random(), function(result) {
defer.resolve(result)
});
},);
return defer.promise();
}

View File

@ -470,7 +470,7 @@ layui.define(['jquery', 'element'], function(exports) {
TitleItem += '<i class="layui-icon layui-unselect layui-tab-close">ဆ</i></li>';
title += TitleItem;
var token = localStorage.getItem("token");
var token = localStorage.getItem("Authorization");
if (option.index == index) {
// 处 理 显 示 内 容

View File

@ -4,11 +4,11 @@ logo:
## 网站名称
title: "MY Style"
## 网站图标
image: "/system/admin/images/logo.png"
image: "/mystyle-cloud-admin-manager/system/admin/images/logo.png"
## 菜单配置
menu:
## 菜单数据来源
data: "/user/menuList"
data: "/mystyle-cloud-admin-manager/user/menuList"
## 菜单接口的请求方式 GET / POST
method: "GET"
## 是否同时只打开一个菜单目录

View File

@ -150,6 +150,7 @@
url: '/article/save',
data: obj,
type: 'post',
data:{}
success: function (result) {
if (result.flag) {
layer.msg(result.message, {icon: 1, time: 1000}, function () {

View File

@ -10,6 +10,10 @@
<link rel="stylesheet" href="${springMacroRequestContext.contextPath}/mystyle-cloud-admin-manager/system/admin/css/load.css" />
<!-- 布 局 样 式 -->
<link rel="stylesheet" href="${springMacroRequestContext.contextPath}/mystyle-cloud-admin-manager/system/admin/css/admin.css" />
<!-- 依 赖 脚 本 -->
<script src="${springMacroRequestContext.contextPath}/mystyle-cloud-admin-manager/system/component/layui/layui.js"></script>
<script src="${springMacroRequestContext.contextPath}/mystyle-cloud-admin-manager/system/component/pear/pear.js"></script>
</head>
<!-- 结 构 代 码 -->
<body class="layui-layout-body pear-admin">
@ -32,7 +36,7 @@
<!-- 头 像 -->
<a href="javascript:;">
<#if loginUser.avatar??>
<img src="${springMacroRequestContext.contextPath}/system/admin/images/avatar.jpg" class="layui-nav-img">
<img src="${springMacroRequestContext.contextPath}/mystyle-cloud-admin-manager/system/admin/images/avatar.jpg" class="layui-nav-img">
<#else >
<img src="${loginUser.avatar!}" class="layui-nav-img">
</#if>
@ -78,9 +82,7 @@
<div class="pear-collasped-pe collaspe">
<a href="#" class="layui-icon layui-icon-shrink-right"></a>
</div>
<!-- 依 赖 脚 本 -->
<script src="${springMacroRequestContext.contextPath}/mystyle-cloud-admin-manager/system/component/layui/layui.js"></script>
<script src="${springMacroRequestContext.contextPath}/mystyle-cloud-admin-manager/system/component/pear/pear.js"></script>
<!-- 框 架 初 始 化 -->
<script>
layui.use(['admin','jquery','convert','popup'], function() {
@ -96,7 +98,7 @@
// 你可以通过 admin.setConfigPath 方法修改配置文件位置
// 你可以通过 admin.setConfigType 方法修改配置文件类型
admin.setConfigType("yml");
admin.setConfigPath("${springMacroRequestContext.contextPath}/system/config/pear.config.yml");
admin.setConfigPath("${springMacroRequestContext.contextPath}/mystyle-cloud-admin-manager/system/config/pear.config.yml");
admin.render();
// 登出逻辑

View File

@ -10,18 +10,6 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>mystyle-cloud-gateway</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
@ -64,12 +52,19 @@
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.4.4</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,50 +0,0 @@
package com.zhangmeng.gateway.feign;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.stream.Collectors;
/**
*
*/
@Configuration
public class FeignOauth2RequestInterceptor implements RequestInterceptor {
@Bean
@ConditionalOnMissingBean
public HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters) {
return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));
}
@Override
public void apply(RequestTemplate requestTemplate) {
// 获取的全部请求信息
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes != null){
HttpServletRequest request = attributes.getRequest();
// 获取所有的请求头信息
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null){
while (headerNames.hasMoreElements()){
// 获取请求头的key
String element = headerNames.nextElement();
// 获取请求头的value
String value = request.getHeader(element);
// 将请求头信息放入到请求头
requestTemplate.header(element,value);
}
}
}
}
}

View File

@ -1,35 +1,34 @@
package com.zhangmeng.gateway.filter;
import com.zhangmeng.gateway.feign.TokenFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpStatus;
import org.springframework.http.codec.multipart.Part;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.TreeMap;
/**
* :( )
*
* */
*/
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
private static final String AUTHORIZE_TOKEN = "Authorization";
@Autowired
private TokenFeign tokenFeign;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
@ -60,6 +59,11 @@ public class AuthorizeFilter implements GlobalFilter, Ordered {
//4.1 从头header中获取令牌数据
String token = request.getHeaders().getFirst(AUTHORIZE_TOKEN);
if (StringUtils.isEmpty(token)) {
//4.3 从请求参数中获取令牌数据
token = request.getQueryParams().getFirst(AUTHORIZE_TOKEN);
}
if (StringUtils.isEmpty(token)) {
//4.2 从cookie中中获取令牌数据
HttpCookie first = request.getCookies().getFirst(AUTHORIZE_TOKEN);
@ -68,31 +72,47 @@ public class AuthorizeFilter implements GlobalFilter, Ordered {
}
}
if(StringUtils.isEmpty(token)){
//4.3 从请求参数中获取令牌数据
token= request.getQueryParams().getFirst(AUTHORIZE_TOKEN);
}
if (StringUtils.isEmpty(token)) {
//4.4. 如果没有数据 结束.
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
ServerHttpRequest new_request = request.mutate().header(AUTHORIZE_TOKEN, "bearer " + token).build();
//5 解析令牌数据 ( 判断解析是否正确,正确 就放行 ,否则 结束)
ServerWebExchange newExchange = exchange.mutate().request(new_request).response(response).build();
try {
//this.tokenFeign.parseToken(token);
} catch (Exception e) {
e.printStackTrace();
//解析失败
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
return chain.filter(exchange);
return chain.filter(newExchange);
}
@Override
public int getOrder() {
return 0;
}
/**
*
* @param serverHttpRequest
* @return
*/
private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest){
//获取请求体
Flux<DataBuffer> body = serverHttpRequest.getBody();
StringBuilder sb = new StringBuilder();
body.subscribe(buffer -> {
byte[] bytes = new byte[buffer.readableByteCount()];
buffer.read(bytes);
DataBufferUtils.release(buffer);
String bodyString = new String(bytes, StandardCharsets.UTF_8);
sb.append(bodyString);
});
return sb.toString();
}
}

View File

@ -0,0 +1,68 @@
package com.zhangmeng.model.bean;
import com.alibaba.fastjson.JSON;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.security.jwt.crypto.sign.RsaVerifier;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.stream.Collectors;
@Component
public class TokenTools {
//公钥
private static final String PUBLIC_KEY = "public.key";
private static String publickey="";
/***
*
* @return
*/
public Map<String,Object> getUserInfo(){
//获取授权信息
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) SecurityContextHolder.getContext().getAuthentication().getDetails();
//令牌解码
return dcodeToken(details.getTokenValue());
}
/***
*
*/
public Map<String,Object> dcodeToken(String token){
//校验Jwt
Jwt jwt = JwtHelper.decodeAndVerify(token, new RsaVerifier(getPubKey()));
//获取Jwt原始内容
String claims = jwt.getClaims();
return JSON.parseObject(claims, Map.class);
}
/**
* Key
* @return Key
*/
public String getPubKey() {
if(!StringUtils.isEmpty(publickey)){
return publickey;
}
Resource resource = new ClassPathResource(PUBLIC_KEY);
try {
InputStreamReader inputStreamReader = new InputStreamReader(resource.getInputStream());
BufferedReader br = new BufferedReader(inputStreamReader);
publickey = br.lines().collect(Collectors.joining("\n"));
return publickey;
} catch (IOException ioe) {
return null;
}
}
}