SpringCloud OAuth2 和 Security 基础框架相关问题汇总
一、公共模块与微服务模块配置类无法生效问题
首先公共异常处理类中的各个注解需要被识别才能够生效

需要在使用该处理异常类的启动器类中的SpringBootApplication 添加对该异常类所在包的扫描

注意:平常SpirngBootApplication不进行属性配置,默认扫描启动类所在的包,所以在配置了扫描其他包的时候,也要配置自身启动类所在的包,还有该服务需要依赖公共模块
实战
通用模块 mms-common (com.xx.common.config.resource)中的 ResourceServerConfig.java 配置类引入到 mms-system 没有生效,折腾了两天时间,终于找到了问题,即服务启动时,只扫描启动类的包,其他引入的公共模块的包的配置类不会自动引入,所以,这里需要在启动类开启扫描包
mms-common/src/main/java/com/baidu/common/config/resource/ResourceServerConfig.java
package com.homay.common.config.resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
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.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.util.FileCopyUtils;
/**
* 资源服务配置
*
* @description
* 每个微服务应用都是一个资源服务器,外部访问都需要token才能进行
*
* @author: kaiyi
* @Date 2021/7/14 14:04
*/
@Slf4j
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
log.info("====================进入到 【mms-common】 [ResourceServerConfig] HttpSecurity configure method ====================");
http.csrf().disable() // 由于使用的是JWT,我们这里不需要csrf
.sessionManagement().disable() // 基于token,所以不需要session
.authorizeRequests()
.antMatchers("/user/test").permitAll() // 匹配不需要资源认证
.antMatchers("/**").authenticated() //匹配需要资源认证路径
.and().headers().cacheControl();
}
/**
* 设置公钥
*
* @param resources
* @throws Exception
*/
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.tokenStore(jwtTokenStore());
}
private TokenStore jwtTokenStore() {
JwtTokenStore jwtTokenStore = new JwtTokenStore(accessTokenConverter());
return jwtTokenStore;
}
@Bean // 放在ioc容器的
public JwtAccessTokenConverter accessTokenConverter() {
//resource 验证token(公钥) authorization 产生 token (私钥)
JwtAccessTokenConverter tokenConverter = new JwtAccessTokenConverter();
String publicKey = null;
try {
ClassPathResource classPathResource = new ClassPathResource("baidu-mms.pub");
byte[] bytes = FileCopyUtils.copyToByteArray(classPathResource.getInputStream());
publicKey = new String(bytes, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
// 不设置这个会出现 Cannot convert access token to JSON [20210712]
tokenConverter.setVerifierKey(publicKey);
// tokenConverter.setVerifier(new RsaVerifier(publicKey));
return tokenConverter;
}
}
System模块启动类
package com.homay.system;
import com.homay.common.annotation.EnableCustomConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* 系统模块
*
* @author: kaiyi
* @Date 2021/7/18 0:31
*/
// @EnableCustomConfig
// 开启扫描包
@SpringBootApplication(scanBasePackages = {"com.baidu.system", "com.baidu.common"})
// @SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class SystemApplication {
public static void main(String[] args) {
SpringApplication.run(SystemApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ System启动成功 ");
}
}
如果觉得上边的开启扫描包方法不太优雅,可以使用注解方式引入加载配置类:
// 开启扫描包
@SpringBootApplication(scanBasePackages = {"com.baidu.system", "com.baidu.common"})
改为:
@EnableCustomConfig
@SpringBootApplication
自定义注解类:mms-common/src/main/java/com/baidu/common/annotation/EnableCustomConfig.java
package com.baid.common.annotation;
import com.baidu.common.config.feign.FeignAutoConfiguration;
import com.baidu.common.config.resource.ResourceServerConfig;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
import org.springframework.scheduling.annotation.EnableAsync;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 开启自定义配置注解类
*
* @author: kaiyi
* @Date 2021/7/27 16:12
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
// 表示通过aop框架暴露该代理对象,AopContext能够访问
@EnableAspectJAutoProxy(exposeProxy = true)
// 开启线程异步执行
@EnableAsync
// 自动加载类
@Import({ ResourceServerConfig.class})
public @interface EnableCustomConfig {
}
调试



二、basicToken生成
OAuth2FeignClient:
@FeignClient(value = "authorization-server")
public interface OAuth2FeignClient {
@PostMapping("/oauth/token")
ResponseEntity<JwtToken> getToken(
@RequestParam("grant_type") String grantType , // 授权类型
@RequestParam("username") String username , // 用户名
@RequestParam("password") String password , // 用户的密码
@RequestParam("login_type") String loginType, // 登录的类型
@RequestHeader("Authorization") String basicToken // Basic Y29pbi1hcGk6Y29pbi1zZWNyZXQ= 由第三方客户端信息加密出现的值
) ;
}
说明:basicToken 参数是从这里来的:


将这里的数据直接写死到
@Value("${basic.token:Basic bW1zLWFwaTptbXMtc2VjcmV0}")
private String basicToken;


为者常成,行者常至
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)