今天本来想靠脸吃饭的,呃呃呃呃....我中午没吃
今天我们来一起探讨一下spring cloud 如何集成 oauth2 搭建服务器
搭建资源服务器
- 导入maven 依赖
<!--security oauth2安全依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
- 编写 ResourceServerConfig 实现 ResourceServerConfigurer
- 配置token存储策略
- 配置鉴权规则
- 在启动类加上@EnableGlobalMethodSecurity(prePostEnabled=true)注解开启注解方式鉴权
public class ResourceServerConfig implements ResourceServerConfigurer {
@Resource
private PermitAllPorperties permitAllPorperties;
@Resource
private TokenStore tokenStore;
/**
* 注入token存取策略
* 开启无状态模式
* 注入token存取策略,我这里使用的JWT所以不需要调用/oauth/check_token,所以不需要配置RemoteTokenService
* @param resource
*/
@Override
public void configure(ResourceServerSecurityConfigurer resource) throws Exception {
resource.tokenStore(tokenStore)
.authenticationEntryPoint(new LwAuthenticationEntryPoint())//自定义认证异常处理
.accessDeniedHandler(new LwAccessDeniedHandler())//自定义权限异常处理
.stateless(true);
}
/**
* 配置拦截规则
* 1、客户端作用域必须是server
* 2、关闭csrf
* 3、将session设置成无状态模式
* permitAllPorperties是我自定义配置类在,他会收集所有带有@IgnoreToken注解方法以及类,放入到IgnoreUrls集合中
* 通过IgnoreUrls在启动时动态配置不需要鉴权的接口
* @param httpSecurity
*/
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests()
.antMatchers(permitAllPorperties.getIgnoreUrls().stream().toArray(String[]::new)).permitAll()
.antMatchers("/**").access("#oauth2.hasScope('server')")
.and()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
/**
* 存储策略
*/
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(jwtAccessTokenConverter());
}
/**
* JWT转换器
*/
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
DefaultAccessTokenConverter defaultConverter = new DefaultAccessTokenConverter();
defaultConverter.setUserTokenConverter(lwUserAuthenticationConverter());
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setAccessTokenConverter(defaultConverter);
converter.setSigningKey("123456");
return converter;
}
}
@Slf4j
@Configuration
public class PermitAllPorperties implements InitializingBean {
private static final Pattern PATTERN = Pattern.compile("\{.*}");
@Resource
private ApplicationContext applicationContext;
//需要忽略鉴权的路径集合
@Getter
@Setter
private List<String> ignoreUrls = new ArrayList<>();
/**
* 收集所有携带@IgnoreToken的方法以及类
* 1、将带有@IgnoreToken注解的方法加入到ignoreUrls集合中,需要将@Pathvariable替换成*
* 2、将带有@IgnoreToken注解的类下所有方法加入到ignoreUrls集合中,需要将@Pathvariable参数替换成*
*
* @param
*/
@Override
public void afterPropertiesSet() throws Exception {
//通过RequestMappingHandlerMapping可以拿到所有方法以及类的信息
RequestMappingHandlerMapping handlerMapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
Map<RequestMappingInfo, HandlerMethod> handlerMethods = handlerMapping.getHandlerMethods();
handlerMethods.forEach((info, method) -> {
//将所有带有IgnoreToken注解的方法请求路径放入到ignoreUrls集合中
IgnoreToken ignoreToken = AnnotationUtil.getAnnotation(method.getMethod(), IgnoreToken.class);
Optional.ofNullable(ignoreToken).ifPresent(ignoreToken1 -> info.getPatternsCondition().getPatterns().forEach(url -> {
ignoreUrls.add(ReUtil.replaceAll(url, PATTERN, "*"));
}));
//将所有带有IgnoreToken注解的类路径放入到ignoreUrls集合中
IgnoreToken controller = AnnotationUtil.getAnnotation(method.getBeanType(), IgnoreToken.class);
Optional.ofNullable(controller).ifPresent(ignoreToken1 -> info.getPatternsCondition().getPatterns().forEach(url -> {
ignoreUrls.add(ReUtil.replaceAll(url, PATTERN, "*"));
}));
});
}
}
@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
@EnableGlobalMethodSecurity(prePostEnabled=true) //开始注解方式验证权限
@MapperScan("com.lw.sys.mapper")
public class SysApplication {
public static void main(String[] args) {
SpringApplication.run(SysApplication.class, args);
}
}