微服务网关Zuul+Spring|微服务网关Zuul+Spring security+Oauth2.0+Jwt + 动态盐值 实现权限控制,开放接口平台(5)

前言 前面我们已经实现了生成access_token,下面我们看如何把access_token转换成jwt的方式给到第三方。
调整 保存策略改成JWT即可
AuthServerConfig:OAuth2的授权服务:主要作用是OAuth2的客户端进行认证与授权

package com.baba.security.auth2.auth; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; import org.springframework.security.oauth2.provider.token.TokenEnhancer; import org.springframework.security.oauth2.provider.token.TokenEnhancerChain; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; import javax.sql.DataSource; import java.util.ArrayList; import java.util.List; /** * OAuth2的授权服务:主要作用是OAuth2的客户端进行认证与授权 * @Author wulongbo * @Date 2021/11/26 9:59 * @Version 1.0 */ @Configuration @EnableAuthorizationServer public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {@Autowired @Qualifier("memberUserDetailsService") public UserDetailsService userDetailsService; @Autowired private DataSource dataSource; @Autowired private AuthenticationManager authenticationManager; @Autowired private TokenStore jwtTokenStore; @Autowired private JwtAccessTokenConverter jwtAccessTokenConverter; @Autowired private TokenEnhancer jwtTokenEnhancer; /** * 配置OAuth2的客户端信息:clientId、client_secret、authorization_type、redirect_url等。 * 实际保存在数据库中 * @param clients * @throws Exception */ @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.jdbc(dataSource); }/** * 1.增加jwt 增强模式 * 2.调用userDetailsService实现UserDetailsService接口,对客户端信息进行认证与授权 * @param endpoints * @throws Exception */ @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { /** * jwt 增强模式 * 对令牌的增强操作就在enhance方法中 * 下面在配置类中,将TokenEnhancer和JwtAccessConverter加到一个enhancerChain中 * * 通俗点讲它做了两件事: * 给JWT令牌中设置附加信息和jti:jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击 * 判断请求中是否有refreshToken,如果有,就重新设置refreshToken并加入附加信息 */ TokenEnhancerChain enhancerChain = new TokenEnhancerChain(); List enhancerList = new ArrayList(); enhancerList.add(jwtTokenEnhancer); enhancerList.add(jwtAccessTokenConverter); enhancerChain.setTokenEnhancers(enhancerList); //将自定义Enhancer加入EnhancerChain的delegates数组中 endpoints.tokenStore(jwtTokenStore) .userDetailsService(userDetailsService) /** * 支持 password 模式 */ .authenticationManager(authenticationManager) .tokenEnhancer(enhancerChain) .accessTokenConverter(jwtAccessTokenConverter); }@Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { security .tokenKeyAccess("permitAll()") //.checkTokenAccess("isAuthenticated()") //解决/oauth/check_token无法访问的问题 .checkTokenAccess("permitAll()") .allowFormAuthenticationForClients(); }}

ResServerConfig:基于OAuth2的资源服务配置类
package com.baba.security.auth2.auth; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; import org.springframework.security.oauth2.provider.token.RemoteTokenServices; import org.springframework.security.oauth2.provider.token.TokenStore; /** * ********在实际项目中此资源服务可以单独提取到资源服务项目中使用******** * * OAuth2的资源服务配置类(主要作用是配置资源受保护的OAuth2策略) * 注:技术架构通常上将用户与客户端的认证授权服务设计在一个子系统(工程)中,而资源服务设计为另一个子系统(工程) * * @Author wulongbo * @Date 2021/11/26 10:01 * @Version 1.0 */ @Configuration @EnableResourceServer @EnableGlobalMethodSecurity(prePostEnabled = true) public class ResServerConfig extends ResourceServerConfigurerAdapter {@Autowired private TokenStore jwtTokenStore; /** * 同认证授权服务配置jwtTokenStore - 单独剥离服务需要开启注释 * @return */ //@Bean //public TokenStore jwtTokenStore() { //return new JwtTokenStore(jwtAccessTokenConverter()); //}/** * 同认证授权服务配置jwtAccessTokenConverter- 单独剥离服务需要开启注释 * 需要和认证授权服务设置的jwt签名相同: "demo" * * @return */ //@Bean //public JwtAccessTokenConverter jwtAccessTokenConverter() { //JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter(); //accessTokenConverter.setSigningKey(Oauth2Constant.JWT_SIGNING_KEY); //accessTokenConverter.setVerifierKey(Oauth2Constant.JWT_SIGNING_KEY); //return accessTokenConverter; //} @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.tokenStore(jwtTokenStore); }/** * 配置受OAuth2保护的URL资源。 * 注意:必须配置sessionManagement(),否则访问受护资源请求不会被OAuth2的拦截器 * ClientCredentialsTokenEndpointFilter与OAuth2AuthenticationProcessingFilter拦截, * 也就是说,没有配置的话,资源没有受到OAuth2的保护。 * * @param http * @throws Exception */ @Override public void configure(HttpSecurity http) throws Exception { /* 注意: 1、必须先加上:.requestMatchers().antMatchers(...),表示对资源进行保护,也就是说,在访问前要进行OAuth认证。 2、接着:访问受保护的资源时,要具有哪里权限。 ------------------------------------ 否则,请求只是被Security的拦截器拦截,请求根本到不了OAuth2的拦截器。 ------------------------------------ requestMatchers()部分说明: Invoking requestMatchers() will not override previous invocations of :: mvcMatcher(String)}, requestMatchers(), antMatcher(String), regexMatcher(String), and requestMatcher(RequestMatcher). */ http // Since we want the protected resources to be accessible in the UI as well we need // session creation to be allowed (it's disabled by default in 2.0.6) //另外,如果不设置,那么在通过浏览器访问被保护的任何资源时,每次是不同的SessionID,并且将每次请求的历史都记录在OAuth2Authentication的details的中 .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) .and() .requestMatchers() .antMatchers("/user", "/res/**","/home/**") .and() .authorizeRequests() .anyRequest().authenticated(); //.antMatchers("/user", "/res/**","/home/**") //.authenticated(); } }

SecurityConfig:其中sourceService就是前面的PermissionService改造一下,针对客户端对外的所有开放接口进行权限控制,所以表区分了一下。
package com.baba.security.auth2.auth; import com.baba.security.auth2.entity.PermissionEntity; import com.baba.security.auth2.entity.Source; import com.baba.security.auth2.service.PermissionService; import com.baba.security.auth2.service.SourceService; import com.baba.security.auth2.service.impl.MemberUserDetailsService; import com.baba.security.common.utils.MD5Util; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; import java.util.List; /** * 配置我们httpBasic 登陆账号和密码 */ @Component @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowired private SourceService sourceService; @Autowired private MemberUserDetailsService memberUserDetailsService; /** * 支持 password 模式(配置) * @return * @throws Exception */ @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); }/** * 引入密码加密类 * @return */ @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { //auth. //inMemoryAuthentication() //.withUser("mayikt") //.password(passwordEncoder().encode("654321")) //.authorities("/*"); // //auth. //inMemoryAuthentication() //.withUser("baidu") //.password(passwordEncoder().encode("54321")) //.authorities("/*"); //System.out.println("==============================="); //System.out.println(passwordEncoder().encode("123456")); //System.out.println(new BCryptPasswordEncoder().encode("12345")); auth.userDetailsService(memberUserDetailsService).passwordEncoder(new PasswordEncoder() { /** * 对密码MD5 * @param rawPassword * @return */ @Override public String encode(CharSequence rawPassword) { return MD5Util.encode((String) rawPassword); }/** * rawPassword 用户输入的密码 * encodedPassword 数据库DB的密码 * @param rawPassword * @param encodedPassword * @return */ @Override public boolean matches(CharSequence rawPassword, String encodedPassword) { String rawPass = MD5Util.encode((String) rawPassword); boolean result = rawPass.equals(encodedPassword); return result; } }); }/** * 配置URL访问授权,必须配置authorizeRequests(),否则启动报错,说是没有启用security技术。 * 注意:在这里的身份进行认证与授权没有涉及到OAuth的技术:当访问要授权的URL时,请求会被DelegatingFilterProxy拦截, *如果还没有授权,请求就会被重定向到登录界面。在登录成功(身份认证并授权)后,请求被重定向至之前访问的URL。 * @param http * @throws Exception */ @Override protected void configure(HttpSecurity http) throws Exception { //http.formLogin() //登记界面,默认是permit All //.and() //.authorizeRequests().antMatchers("/","/home").permitAll() //不用身份认证可以访问 //.and() //.authorizeRequests().anyRequest().authenticated() //其它的请求要求必须有身份认证 //.and() //.csrf() //防止CSRF(跨站请求伪造)配置 //.requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize")).disable(); Source source = new Source(); List allPermission = sourceService.findByAll(source); ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry expressionInterceptUrlRegistry = http.authorizeRequests(); allPermission.forEach((s) -> { expressionInterceptUrlRegistry.antMatchers(s.getUrl()). hasRole(s.getTag()); }); http .formLogin() .and() //.authorizeRequests().antMatchers("/","/home").permitAll() //不用身份认证可以访问 //.and() //允许不登陆就可以访问的方法,多个用逗号分隔 .authorizeRequests() //跨域请求会先进行一次options请求 //.antMatchers(HttpMethod.OPTIONS).permitAll() //.antMatchers("/","/home").permitAll() //不用身份认证可以访问 //其他的需要授权后访问 .antMatchers("/**").authenticated() //其它的请求要求必须有身份认证 //.anyRequest().authenticated() //其它的请求要求必须有身份认证 //// 加一句这个 .and() .csrf().disable(); //关跨域保护 }}

Oauth2Constant :当然签名可以改动态
package com.baba.security.auth2.constant; /** * @Author wulongbo * @Date 2021/11/26 9:56 * @Version 1.0 */ public class Oauth2Constant { /**************************************Oauth2参数配置**********************************************/ /** * JWT_SIGNING_KEY */ public static final String JWT_SIGNING_KEY = "jwtsigningkey"; }

JWTokenEnhancer:自定义TokenEnhancer
package com.baba.security.auth2.config; import com.baba.security.auth2.entity.User; import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.token.TokenEnhancer; import java.util.HashMap; import java.util.Map; /** * TokenEnhancer:在AuthorizationServerTokenServices 实现存储访问令牌之前增强访问令牌的策略。 * 自定义TokenEnhancer的代码:把附加信息加入oAuth2AccessToken中 * * @Author wulongbo * @Date 2021/11/26 9:58 * @Version 1.0 */ public class JWTokenEnhancer implements TokenEnhancer {/** * 重写enhance方法,将附加信息加入oAuth2AccessToken中 * * @param oAuth2AccessToken * @param oAuth2Authentication * @return */ @Override public OAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication oAuth2Authentication) { Map map = new HashMap(); User user = (User)oAuth2Authentication.getPrincipal(); map.put("id", user.getId()); map.put("jwt-ext", "把把智能科技"); ((DefaultOAuth2AccessToken) oAuth2AccessToken).setAdditionalInformation(map); return oAuth2AccessToken; } }

JwtTokenConfig:JwtTokenConfig配置类
package com.baba.security.auth2.config; import com.baba.security.auth2.constant.Oauth2Constant; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.oauth2.provider.token.TokenEnhancer; 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; /** * JwtTokenConfig配置类 * 使用TokenStore将引入JwtTokenStore * * 注:Spring-Sceurity使用TokenEnhancer和JwtAccessConverter增强jwt令牌 * @author wulongbo * @date 2021-11-27 */ @Configuration public class JwtTokenConfig {@Bean public TokenStore jwtTokenStore() { return new JwtTokenStore(jwtAccessTokenConverter()); }/** * JwtAccessTokenConverter:TokenEnhancer的子类,帮助程序在JWT编码的令牌值和OAuth身份验证信息之间进行转换(在两个方向上),同时充当TokenEnhancer授予令牌的时间。 * 自定义的JwtAccessTokenConverter:把自己设置的jwt签名加入accessTokenConverter中(这里设置'demo',项目可将此在配置文件设置) * @return */ @Bean public JwtAccessTokenConverter jwtAccessTokenConverter() { JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter(); //accessTokenConverter.setVerifierKey(Oauth2Constant.JWT_SIGNING_KEY); accessTokenConverter.setSigningKey(Oauth2Constant.JWT_SIGNING_KEY); return accessTokenConverter; }/** * 引入自定义JWTokenEnhancer: * 自定义JWTokenEnhancer实现TokenEnhancer并重写enhance方法,将附加信息加入oAuth2AccessToken中 * @return */ @Bean public TokenEnhancer jwtTokenEnhancer(){ return new JWTokenEnhancer(); } }

GetSecret (获取Header以及加密后的密码)
package com.baba.security.auth2.utils; import org.apache.commons.codec.binary.Base64; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import java.nio.charset.Charset; /** * (获取Header以及加密后的密码) * @Author wulongbo * @Date 2021/11/26 10:50 * @Version 1.0 */ public class GetSecret {/** * 对应数据库中的client_id的值 */ private static final String APP_KEY = "mayikt_appid"; /** * 对应数据库中的client_secret的值 */ private static final String SECRET_KEY = "123456"; /** * main方法执行程序获取到数据库中加密后的client_secret和请求头中的getHeader * @param args */ public static void main(String[] args){ System.out.println(); System.out.println("client_secret: "+new BCryptPasswordEncoder().encode(SECRET_KEY)); System.out.println("getHeader: "+getHeader()); }/** * 构造Basic Auth认证头信息 * * @return */ private static String getHeader() { String auth = APP_KEY + ":" + SECRET_KEY; byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(Charset.forName("US-ASCII"))); String authHeader = "Basic " + new String(encodedAuth); return authHeader; } }

pom这里不再使用cloud,使用boot的 :
【微服务网关Zuul+Spring|微服务网关Zuul+Spring security+Oauth2.0+Jwt + 动态盐值 实现权限控制,开放接口平台(5)】zuul-auth com.babaznkj.com 1.0-SNAPSHOT 4.0.0auth28 8 com.babaznkj.com common mysql mysql-connector-java ${mysql.version} org.mybatis.spring.boot mybatis-spring-boot-starter ${mybatis.starter.version} com.alibaba druid-spring-boot-starter ${druid.starter.version} org.springframework.security.oauth.boot spring-security-oauth2-autoconfigure 2.0.0.RELEASE org.springframework.boot spring-boot-starter-integration org.springframework.integration spring-integration-core org.springframework.integration spring-integration-stream org.springframework.integration spring-integration-mqtt org.springframework.boot spring-boot-starter-data-mongodb org.springframework.boot spring-boot-starter-data-jpa org.apache.commons commons-collections4 4.1

OpenApiUtils
package com.baba.security.auth2.utils; import com.baba.security.auth2.constant.Oauth2Constant; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.lang.Assert; import javax.servlet.http.HttpServletRequest; import java.util.Date; public class OpenApiUtils {/** * 获取用户id * * @param request * @return */ public static Long getUserId(HttpServletRequest request) { String accessToken= request.getHeader("access_token"); Assert.hasText(accessToken, "accessToken parameter must not be empty or null"); final Claims claims = Jwts.parser() .setSigningKey(Oauth2Constant.JWT_SIGNING_KEY.getBytes()) .parseClaimsJws(accessToken) .getBody(); Long id = Long.valueOf(claims.get("id").toString()); return id; }/** * 是否过期 * * @param request * @return */ public static boolean isExpiration(HttpServletRequest request) { String accessToken= request.getHeader("access_token"); Claims claims = Jwts.parser().setSigningKey(Oauth2Constant.JWT_SIGNING_KEY.getBytes()).parseClaimsJws(accessToken).getBody(); return claims.getExpiration().before(new Date()); }}

测试访问的Controller:
HomeController
package com.baba.security.auth2.controller; import com.baba.security.auth2.utils.OpenApiUtils; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; /** * @Author wulongbo * @Date 2021/11/26 10:03 * @Version 1.0 */ @RestController @RequestMapping("/home") public class HomeController {@PreAuthorize("hasRole('/home/getHome')") @RequestMapping("/getHome") public String home(HttpServletRequest request) { Long id = OpenApiUtils.getUserId(request); return "home page" + id; }@PreAuthorize("hasRole('/home/getindex')") @RequestMapping("/getindex") public String index(HttpServletRequest request) { Long id = OpenApiUtils.getUserId(request); return "index page:" + id; } }

ResController
package com.baba.security.auth2.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.security.Principal; /** * @Author wulongbo * @Date 2021/11/26 10:04 * @Version 1.0 */@RestController public class ResController {@RequestMapping("/res/getMsg") public String getMsg(String msg, Principal principal) {//principal中封装了客户端(用户,也就是clientDetails,区别于Security的UserDetails,其实clientDetails中也封装了UserDetails),不是必须的参数,除非你想得到用户信息,才加上principal。 return "Get the msg: "+msg; } }

UserController
package com.baba.security.auth2.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.security.Principal; /** * 用户服务接口 * * @author Tom * @date 2020-09-04 */ @RestController public class UserController { @RequestMapping("/user") public Principal user(Principal principal) { //principal在经过security拦截后,是org.springframework.security.authentication.UsernamePasswordAuthenticationToken //在经OAuth2拦截后,是OAuth2Authentication return principal; } }

oauth_client_details表调整sql:
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for oauth_client_details -- ---------------------------- DROP TABLE IF EXISTS `oauth_client_details`; CREATE TABLE `oauth_client_details`( `client_id` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '主键,必须唯一,用于唯一标识每一个客户端', `resource_ids` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '客户端所能访问的资源id集合', `client_secret` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '用于指定客户端的访问密匙', `scope` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '指定客户端申请的权限范围,可选值包括read,write,trust', `authorized_grant_types` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '指定客户端支持的grant_type,可选值包括 authorization_code,password,refresh_token,implicit,client_credentials', `web_server_redirect_uri` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '客户端的重定向URI', `authorities` varbinary(6000) NULL DEFAULT NULL COMMENT '指定客户端所拥有的Spring Security的权限值', `access_token_validity` int(11) NULL DEFAULT NULL COMMENT '设定客户端的access_token的有效时间值', `refresh_token_validity` int(11) NULL DEFAULT NULL COMMENT '设定客户端的refresh_token的有效时间值(单位:秒),可选, 若不设定值则使用默认的有效时间值(60 * 60 * 24 * 30, 30天).', `additional_information` varchar(4096) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '这是一个预留的字段,在Oauth的流程中没有实际的使用,可选,但若设置值,必须是JSON格式的 数据', `autoapprove` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '设置用户是否自动Approval操作, 默认值为 ‘false’', PRIMARY KEY (`client_id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Records of oauth_client_details -- ---------------------------- INSERT INTO `oauth_client_details` VALUES ('baidu', 'mayikt_resource,user,device', '$2a$10$32N/ptu3jY0WjFH0qLbcEO2ZcCg4gYCJvMbwmqzf84qNCcDFBLl4q', 'read,write', 'authorization_code', 'http://www.mayikt.com/callback', NULL, NULL, NULL, NULL, NULL); INSERT INTO `oauth_client_details` VALUES ('mayikt_appid', NULL, '$2a$10$6/Sab9Au.CdKqyE4x0gr0OJZrzrcDCWZ9GLqMDF6KX.jHad5vlkeO', 'read,write,trust', 'authorization_code,refresh_token,client_credentials', 'http://localhost:8082/res/getMsg', NULL, 36000, 36000, NULL, '1'); INSERT INTO `oauth_client_details` VALUES ('zdfd', 'mayikt_resource', '$2a$10$6/Sab9Au.CdKqyE4x0gr0OJZrzrcDCWZ9GLqMDF6KX.jHad5vlkeO', 'read,write,trust', 'authorization_code', 'http://www.mayikt.com/callback', NULL, NULL, NULL, NULL, NULL); SET FOREIGN_KEY_CHECKS = 1;

浏览器中输入如下地址:获取授权码code:
http://localhost:8082/oauth/authorize?client_id=mayikt_appid&response_type=code&redirect_uri=http://localhost:8082/res/getMsg
微服务网关Zuul+Spring|微服务网关Zuul+Spring security+Oauth2.0+Jwt + 动态盐值 实现权限控制,开放接口平台(5)
文章图片

咱们用户名为手机号,输入手机号17343759359,密码132465[后台会MD5加密比对]
微服务网关Zuul+Spring|微服务网关Zuul+Spring security+Oauth2.0+Jwt + 动态盐值 实现权限控制,开放接口平台(5)
文章图片

点击授权,获取授权码
微服务网关Zuul+Spring|微服务网关Zuul+Spring security+Oauth2.0+Jwt + 动态盐值 实现权限控制,开放接口平台(5)
文章图片

根据授权码获取access_token:
**备注:**有的文章说这里请求头中需带 Authrization:加上工具类GetSecret生成的Basic bWF5aWt0X2FwcGlkOjEyMzQ1Ng==,但是我测试不加也行
微服务网关Zuul+Spring|微服务网关Zuul+Spring security+Oauth2.0+Jwt + 动态盐值 实现权限控制,开放接口平台(5)
文章图片

localhost:8082/oauth/token
form-data参数如下
参数 参数值
grant_type authorization_code
code ZXfgp3
client_id mayikt_appid
client_secret 123456
redirect_uri http://localhost:8082/res/getMsg
微服务网关Zuul+Spring|微服务网关Zuul+Spring security+Oauth2.0+Jwt + 动态盐值 实现权限控制,开放接口平台(5)
文章图片

检查access_token:
http://localhost:8082/oauth/c...
微服务网关Zuul+Spring|微服务网关Zuul+Spring security+Oauth2.0+Jwt + 动态盐值 实现权限控制,开放接口平台(5)
文章图片

我们访问一下资源服务:
http://localhost:8082/res/get...
微服务网关Zuul+Spring|微服务网关Zuul+Spring security+Oauth2.0+Jwt + 动态盐值 实现权限控制,开放接口平台(5)
文章图片

访问我们权限控制的controller
http://localhost:8082/home/ge...
微服务网关Zuul+Spring|微服务网关Zuul+Spring security+Oauth2.0+Jwt + 动态盐值 实现权限控制,开放接口平台(5)
文章图片

当然我们的17343759359用户我给了所有权限,我登录一个没有getindex权限的用户13549553864时候,请求/home/getindex看一看【已免去前面的授权步骤】
http://localhost:8082/home/ge...
访问失败
微服务网关Zuul+Spring|微服务网关Zuul+Spring security+Oauth2.0+Jwt + 动态盐值 实现权限控制,开放接口平台(5)
文章图片

自此我们完成了jwt方式来实现开放接口平台

    推荐阅读