From a1ec0394166069b8a8e8ea0317e291b3985f2ce0 Mon Sep 17 00:00:00 2001 From: kdyzm Date: Wed, 13 Jan 2021 18:15:21 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=B7=BB=E5=8A=A0JWT=20Token=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E8=BF=87=E6=BB=A4=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gateway-server/pom.xml | 5 ++ .../gateway/server/filter/TokenFilter.java | 64 ++++++++++++++++++- .../src/main/resources/application.yaml | 10 ++- 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/gateway-server/pom.xml b/gateway-server/pom.xml index e7fc491..1949b50 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 a78d24b..e7e16c9 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 aadb6ed..4e0b5db 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 -- Gitee From 98c6c4dbe00b676f6a9a98bb7ee822d5129e8c03 Mon Sep 17 00:00:00 2001 From: kdyzm Date: Wed, 13 Jan 2021 18:19:23 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E8=B5=84=E6=BA=90=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E5=8F=96=E6=B6=88=E6=89=80=E6=9C=89oath=E5=92=8Cjwt=E7=9A=84?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E5=92=8C=E9=85=8D=E7=BD=AE=EF=BC=8C=E4=BB=85?= =?UTF-8?q?=E4=BF=9D=E7=95=99spring=20security=E7=9A=84=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=92=8C=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resource-server/pom.xml | 14 +++++++++----- .../server/config/ResouceServerConfig.java | 10 +++++++--- .../study/resource/server/config/TokenConfig.java | 8 ++++++-- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/resource-server/pom.xml b/resource-server/pom.xml index 2f7a535..5e13430 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 95fe33b..cdca3a9 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 2802bb1..e1e77eb 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; } } +*/ -- Gitee From 81d3b030ef40f0431f064d4dd1ca061d75f03c66 Mon Sep 17 00:00:00 2001 From: kdyzm Date: Wed, 13 Jan 2021 18:20:51 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E8=B5=84=E6=BA=90=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0token=E8=BF=87=E6=BB=A4=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/config/WebSecurityConfig.java | 20 +++++-- .../server/controller/OrderController.java | 9 +++- .../server/filter/AuthFilterCustom.java | 54 +++++++++++++++++++ .../resource/server/models/JwtTokenInfo.java | 28 ++++++++++ 4 files changed, 106 insertions(+), 5 deletions(-) create mode 100644 resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/filter/AuthFilterCustom.java create mode 100644 resource-server/src/main/java/com/kdyzm/spring/security/oauth/study/resource/server/models/JwtTokenInfo.java 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 a5a3e43..3afe9b8 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 86710a2..c622ee5 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 0000000..47e7c0e --- /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 0000000..fad16d0 --- /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; + +} -- Gitee