SpringCloud oauth2 jwt gateway demo
2023-02-18 16:23:39 时间
前言
uaa 认证服务
@Configuration @EnableAuthorizationServer @AllArgsConstructor public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("user-service") .secret("123456") .scopes("service") .autoApprove(true) .authorizedGrantTypes("implicit", "refresh_token", "password", "authorization_code") .accessTokenValiditySeconds(12 * 300);//5min过期 } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.tokenStore(tokenStore()).tokenEnhancer(jwtTokenEnhancer()).authenticationManager(authenticationManager); } @Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer .tokenKeyAccess("permitAll()") .checkTokenAccess("isAuthenticated()").allowFormAuthenticationForClients().passwordEncoder(NoOpPasswordEncoder.getInstance()); /** * 必须设置allowFormAuthenticationForClients 否则没有办法用postman获取token * 也需要指定密码加密方式BCryptPasswordEncoder */ } @Autowired @Qualifier("authenticationManagerBean") private AuthenticationManager authenticationManager; @Bean public TokenStore tokenStore() { return new JwtTokenStore(jwtTokenEnhancer()); } @Bean protected JwtAccessTokenConverter jwtTokenEnhancer() { JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter(); jwtAccessTokenConverter.setKeyPair(keyPair()); return jwtAccessTokenConverter; } @Bean public KeyPair keyPair() { KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("demojwt.jks"), "keystorepass".toCharArray()); return keyStoreKeyFactory.getKeyPair("jwt", "keypairpass".toCharArray()); }
uaa websecurityconfig
@Configuration
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.exceptionHandling()
.authenticationEntryPoint((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
.and()
.authorizeRequests()
.antMatchers("/.well-known/jwks.json").permitAll()
.antMatchers("/**").authenticated()
.and()
.httpBasic();
}
@Autowired
UserServiceDetail userServiceDetail;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userServiceDetail)
.passwordEncoder(new BCryptPasswordEncoder());
}
}
资源服务配置
@EnableWebFluxSecurity
public class SecurityConfig {
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http
.authorizeExchange()
.pathMatchers("/**").authenticated()
.anyExchange()
.authenticated()
.and()
.oauth2ResourceServer()
.jwt();
return http.build();
}
}
网关配置
@SpringBootApplication
@EnableEurekaClient
public class GatewayServiceApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayServiceApplication.class, args);
}
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("resource", r -> r.path("/resource/**")
.filters(f -> f.stripPrefix(1))//去掉第一层前缀如果是/api/oauth这种 就stripPrefix(2)
.uri("lb://resource-service")) // Prevents cookie being sent downstream
// .uri("http://localhost:9090")) // Taking advantage of docker naming
.route("uaa",r -> r.path("/uaa/**")
.filters(f -> f.stripPrefix(1))
.uri("lb://uaa-service"))
.build();
}
}
演示
直接授权
![](https://upload-images.jianshu.io/upload_images/6380064-65b762c1dd05eea7.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)
访问开放资源
![](https://upload-images.jianshu.io/upload_images/6380064-05718c8e3cc4034b.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)
访问需要授权
![](https://upload-images.jianshu.io/upload_images/6380064-c54f30555aba2a09.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)
带上token访问
![](https://upload-images.jianshu.io/upload_images/6380064-38fb1c5d257f2999.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)
经过网关转发授权
![](https://upload-images.jianshu.io/upload_images/6380064-33af74239ab71c48.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)
经过网关访问开发资源
http://localhost:8068/resource/hello
![](https://upload-images.jianshu.io/upload_images/6380064-94b92454444facd4.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)
经过网关访问授权资源
http://localhost:8068/resource/foo
![](https://upload-images.jianshu.io/upload_images/6380064-6095728195a0793b.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)
带上token访问授权资源
http://localhost:8068/resource/foo
![](https://upload-images.jianshu.io/upload_images/6380064-5e85882a622b0d99.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)
相关文章
- 我是如何一步步的在并行编程中将lock锁次数降到最低实现无锁编程
- Linq中带有迭代索引的Select扩展方法,为啥知道的人不多呢?
- 一个lock锁就可以分出低中高水平的程序员对问题的处置方式
- 多角度让你彻底明白yield语法糖的用法和原理及在C#函数式编程中的作用
- Linq下有一个非常实用的SelectMany方法,很多人却不会用
- 当模板方法遇到了委托函数,你的代码又可以精简了
- 为什么要用内插字符串代替string.format
- 如何让多个不同类型的后端网站用一个nginx进行反向代理实际场景分析
- 8天入门docker系列 —— 第八天 让程序跑在swarm集群上
- 8天入门docker系列 —— 第七天 让你的container实现跨主机访问
- 8天入门docker系列 —— 第六天 搭建自己的私有镜像仓库Registry
- 8天入门docker系列 —— 第五天 使用aspnetcore小案例熟悉容器互联和docker-compose一键部署
- 8天入门docker系列 —— 第四天 使用aspnetcore小案例熟悉端口映射和挂载目录
- 8天入门docker系列 —— 第三天 使用aspnetcore小案例熟悉对镜像的操控
- 8天入门docker系列 —— 第二天 通过一个aspnetcore程序加深对容器的理解
- 8天入门docker系列 —— 第一天 docker出现前的困惑和简单介绍
- jenkins + supervisor + ansible 实现netcore程序的多机一键部署
- netcore使用 jenkins + supervisor 实现standalone下多副本自动化发布
- 看看redis中那些好玩的module (sql on redis, bf/cf on redis)
- 使用docker-compose 一键部署你的分布式调用链跟踪框架skywalking