diff --git a/gateway-server/pom.xml b/gateway-server/pom.xml
index e7fc4914bc9664d482c9ea4be586e9120e496714..1949b50d3372a68a8bc1d2a0f8363a2eff887c9f 100644
--- a/gateway-server/pom.xml
+++ b/gateway-server/pom.xml
@@ -30,6 +30,11 @@
org.projectlombok
lombok
+
+
+ org.springframework.security
+ spring-security-jwt
+
\ No newline at end of file
diff --git a/gateway-server/src/main/java/com/kdyzm/spring/security/oauth/study/gateway/server/filter/TokenFilter.java b/gateway-server/src/main/java/com/kdyzm/spring/security/oauth/study/gateway/server/filter/TokenFilter.java
index a78d24b69d42bab6906756d8a2815288a81a9d42..e7e16c92132d63c8c774374ed99af1afd57a07ed 100644
--- a/gateway-server/src/main/java/com/kdyzm/spring/security/oauth/study/gateway/server/filter/TokenFilter.java
+++ b/gateway-server/src/main/java/com/kdyzm/spring/security/oauth/study/gateway/server/filter/TokenFilter.java
@@ -1,7 +1,22 @@
package com.kdyzm.spring.security.oauth.study.gateway.server.filter;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.cloud.gateway.handler.predicate.HeaderRoutePredicateFactory;
+import org.springframework.core.Ordered;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.security.jwt.Jwt;
+import org.springframework.security.jwt.JwtHelper;
+import org.springframework.security.jwt.crypto.sign.MacSigner;
import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
/**
* @author kdyzm
@@ -9,6 +24,53 @@ import org.springframework.stereotype.Component;
@Component
@Slf4j
-public class TokenFilter {
+public class TokenFilter implements GlobalFilter, Ordered {
+
+
+ private static final String BEAR_HEADER = "Bearer ";
+
+ /**
+ * 该值要和auth-server中配置的签名相同
+ *
+ * com.kdyzm.spring.security.auth.center.config.TokenConfig#SIGNING_KEY
+ */
+ private static final String SIGNING_KEY = "auth123";
+
+ @Override
+ public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+ String token = exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
+ //如果没有token,则直接返回401
+ if(StringUtils.isEmpty(token)){
+ return unAuthorized(exchange);
+ }
+ //验签并获取PayLoad
+ String payLoad;
+ try {
+ Jwt jwt = JwtHelper.decodeAndVerify(token.replace(BEAR_HEADER,""), new MacSigner(SIGNING_KEY));
+ payLoad = jwt.getClaims();
+ } catch (Exception e) {
+ log.error("验签失败",e);
+ return unAuthorized(exchange);
+ }
+ //将PayLoad数据放到header
+ ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
+ builder.header("token-info", payLoad).build();
+ //继续执行
+ return chain.filter(exchange.mutate().request(builder.build()).build());
+ }
+
+ private Mono unAuthorized(ServerWebExchange exchange){
+ exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
+ return exchange.getResponse().setComplete();
+ }
+ /**
+ * 将该过滤器的优先级设置为最高,因为只要认证不通过,就不能做任何事情
+ *
+ * @return
+ */
+ @Override
+ public int getOrder() {
+ return Ordered.HIGHEST_PRECEDENCE;
+ }
}
diff --git a/gateway-server/src/main/resources/application.yaml b/gateway-server/src/main/resources/application.yaml
index aadb6ed5518d43599426400b72c6ae4c32d0dc73..4e0b5db1cd95482fc2d7f40d1ee633383f059aef 100644
--- a/gateway-server/src/main/resources/application.yaml
+++ b/gateway-server/src/main/resources/application.yaml
@@ -4,10 +4,14 @@ spring:
cloud:
gateway:
routes:
- - id: baidu_route
- uri: https://www.baidu.com
+ - id: resource_server
+ uri: "lb://resource-server"
predicates:
- - Path=/**
+ - Path=/r**
+# - id: baidu_route
+# uri: https://www.baidu.com
+# predicates:
+# - Path=/**
application:
name: gateway-server
diff --git a/resource-server/pom.xml b/resource-server/pom.xml
index 2f7a5350b6bd475e49910da95966537e530edfd8..5e13430fc79d65fe1220cbce9e4d661ad44330a9 100644
--- a/resource-server/pom.xml
+++ b/resource-server/pom.xml
@@ -24,13 +24,17 @@
org.springframework.cloud
spring-cloud-starter-security
-
+
+
+
+
+
+
+ javax.interceptor
+ javax.interceptor-api
com.alibaba
diff --git a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/config/ResouceServerConfig.java b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/config/ResouceServerConfig.java
index 95fe33b3bff63613668a6ddf200162637efb330f..cdca3a9d26fd96fb240b091164c76994e27a9ee6 100644
--- a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/config/ResouceServerConfig.java
+++ b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/config/ResouceServerConfig.java
@@ -1,4 +1,5 @@
package com.kdyzm.spring.security.oauth.study.resource.server.config;
+/*
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@@ -13,11 +14,13 @@ import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
+*/
/**
* @author kdyzm
- */
-@Configuration
-@EnableResourceServer
+ *//*
+
+//@Configuration
+//@EnableResourceServer
public class ResouceServerConfig extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID= "res1";
@@ -59,3 +62,4 @@ public class ResouceServerConfig extends ResourceServerConfigurerAdapter {
}
+*/
diff --git a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/config/TokenConfig.java b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/config/TokenConfig.java
index 2802bb1afaaa6ff108406c2c5f3e56bb01c55f2f..e1e77ebb13e8b450fba6e5bcc724348dd2ec2432 100644
--- a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/config/TokenConfig.java
+++ b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/config/TokenConfig.java
@@ -1,4 +1,5 @@
package com.kdyzm.spring.security.oauth.study.resource.server.config;
+/*
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -6,10 +7,12 @@ import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
+*/
/**
* @author kdyzm
- */
-@Configuration
+ *//*
+
+//@Configuration
public class TokenConfig {
private static final String SIGNING_KEY = "auth123";
@@ -27,3 +30,4 @@ public class TokenConfig {
return jwtAccessTokenConverter;
}
}
+*/
diff --git a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/config/WebSecurityConfig.java b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/config/WebSecurityConfig.java
index a5a3e431e0e1b9f0968852544eb45b5ba8614c10..3afe9b83116b83c376804bc1be2176f44c507354 100644
--- a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/config/WebSecurityConfig.java
+++ b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/config/WebSecurityConfig.java
@@ -1,9 +1,13 @@
package com.kdyzm.spring.security.oauth.study.resource.server.config;
+import com.kdyzm.spring.security.oauth.study.resource.server.filter.AuthFilterCustom;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
/**
* @author kdyzm
@@ -12,14 +16,22 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+ @Autowired
+ private AuthFilterCustom authFilterCustom;
+
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.authorizeRequests()
- .antMatchers("/r/r1").hasAuthority("p2")
- .antMatchers("/r/r2").hasAuthority("p2")
- .antMatchers("/**").authenticated()//所有的r/**请求必须认证通过
- .anyRequest().permitAll();//其它所有请求都可以随意访问
+// .antMatchers("/r/r1").hasAuthority("p2")
+// .antMatchers("/r/r2").hasAuthority("p2")
+ .antMatchers("/**").authenticated()//所有的请求必须认证通过
+ .anyRequest().permitAll()//其它所有请求都可以随意访问
+ .and()
+ .addFilterAfter(authFilterCustom, BasicAuthenticationFilter.class)//添加过滤器
+ .sessionManagement()
+ .sessionCreationPolicy(SessionCreationPolicy.STATELESS);//禁用session
+
}
}
diff --git a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/controller/OrderController.java b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/controller/OrderController.java
index 86710a245d5b68f674533c368a1fd239aa8c50ed..c622ee57ef0c2f02ae7fe34fece582e08c3c0581 100644
--- a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/controller/OrderController.java
+++ b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/controller/OrderController.java
@@ -5,6 +5,9 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Enumeration;
+
/**
* @author kdyzm
*/
@@ -14,7 +17,11 @@ public class OrderController {
@GetMapping("/r1")
@PreAuthorize("hasAnyAuthority('p1')")
- public String r1(){
+ public String r1(HttpServletRequest httpServletRequest){
+ Enumeration headerNames = httpServletRequest.getHeaderNames();
+ while(headerNames.hasMoreElements()){
+ log.info(headerNames.nextElement());
+ }
return "访问资源r1";
}
}
diff --git a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/filter/AuthFilterCustom.java b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/filter/AuthFilterCustom.java
new file mode 100644
index 0000000000000000000000000000000000000000..47e7c0e6bc50c59d70cf8b2475b87ec2d0d05cd0
--- /dev/null
+++ b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/filter/AuthFilterCustom.java
@@ -0,0 +1,54 @@
+package com.kdyzm.spring.security.oauth.study.resource.server.filter;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.kdyzm.spring.security.oauth.study.resource.server.models.JwtTokenInfo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.authority.AuthorityUtils;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import org.springframework.web.filter.GenericFilterBean;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * @author kdyzm
+ */
+@Component
+@Slf4j
+public class AuthFilterCustom extends OncePerRequestFilter {
+
+ @Override
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
+ ObjectMapper objectMapper = new ObjectMapper();
+ String tokenInfo=request.getHeader("token-info");
+ if(StringUtils.isEmpty(tokenInfo)){
+ log.info("未找到token信息");
+ filterChain.doFilter(request,response);
+ return;
+ }
+ JwtTokenInfo jwtTokenInfo = objectMapper.readValue(tokenInfo, JwtTokenInfo.class);
+ log.info("tokenInfo={}",objectMapper.writeValueAsString(jwtTokenInfo));
+ List authorities1 = jwtTokenInfo.getAuthorities();
+ String[] authorities=new String[authorities1.size()];
+ authorities1.toArray(authorities);
+ //将用户信息和权限填充 到用户身份token对象中
+ UsernamePasswordAuthenticationToken authenticationToken
+ = new UsernamePasswordAuthenticationToken(jwtTokenInfo.getUser_name(),null, AuthorityUtils.createAuthorityList(authorities));
+ authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+ //将authenticationToken填充到安全上下文
+ SecurityContextHolder.getContext().setAuthentication(authenticationToken);
+ filterChain.doFilter(request,response);
+ }
+}
diff --git a/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/models/JwtTokenInfo.java b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/models/JwtTokenInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..fad16d0110325cfd53bd7e63e886f9e0dc804180
--- /dev/null
+++ b/resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/models/JwtTokenInfo.java
@@ -0,0 +1,28 @@
+package com.kdyzm.spring.security.oauth.study.resource.server.models;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author kdyzm
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class JwtTokenInfo {
+
+ private List aud;
+ private String user_name;
+ private List scope;
+ private Date exp;
+ private List authorities;
+ private String jti;
+ private String client_id;
+
+}