文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Spring Security中使用Keycloak作为认证授权服务器

2024-12-02 23:57

关注

Keycloak对流行的Java应用提供了适配器。在系列文章的上一篇我们演示了针对Spring Boot的安全保护,用的就是适配器的一种。Keycloak同样提供Spring Security的适配器,后续的几篇文章我们就来共同学习Spring Security适配器的使用。

Keycloak的安装可参考前面的系列教程。

适配器集成

在Spring 应用中我们集成keycloak-spring-security-adapter:

  1.  
  2.     org.keycloak 
  3.     keycloak-spring-security-adapter 
  4.     15.0.0 
  5.  

在Spring Boot中可以这样集成:

  1.  
  2.     org.springframework.boot 
  3.     spring-boot-starter-security 
  4.  
  5.  
  6.     org.keycloak 
  7.     keycloak-spring-boot-starter 
  8.     15.0.0 
  9.         

然后就能利用Spring Security的特性来集成Keycloak。Keycloak 提供了一个 KeycloakWebSecurityConfigurerAdapter 作为创建WebSecurityConfigurer 实例的方便基类。我们可以编写了一个配置类来定制我们的安全策略,就像这样:

  1. @KeycloakConfiguration 
  2. public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter 
  3.      
  4.     @Autowired 
  5.     public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
  6.         auth.authenticationProvider(keycloakAuthenticationProvider()); 
  7.     } 
  8.  
  9.      
  10.     @Bean 
  11.     @Override 
  12.     protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { 
  13.         return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl()); 
  14.     } 
  15.  
  16.       
  17.     @Override 
  18.     protected void configure(HttpSecurity http) throws Exception 
  19.     { 
  20.         super.configure(http); 
  21.         http 
  22.                 .authorizeRequests() 
  23.                 .antMatchers("/customers*").hasRole("USER"
  24.                 .antMatchers("/admin 
  25.   @Bean 
  26.   public KeycloakConfigResolver keycloakConfigResolver() { 
  27.       return new KeycloakSpringBootConfigResolver(); 
  28.   } 

然后复用Spring Boot的application.yaml的配置项:

复用Spring Boot配置项

原来的角色资源映射约束失效。

自定义实现

你也可以自定义写解析,这个时候json形式已经不重要了,你可以将json文件的内容存储到任何你擅长的地方。

  1.  
  2. @Bean 
  3. public KeycloakConfigResolver fileKeycloakConfigResolver() { 
  4.     return  new KeycloakConfigResolver() { 
  5.         @SneakyThrows 
  6.         @Override 
  7.         public KeycloakDeployment resolve(HttpFacade.Request request) { 
  8.             // json 文件放到resources 文件夹下 
  9.             ClassPathResource classPathResource = new ClassPathResource("./keycloak.json"); 
  10.             AdapterConfig adapterConfig = new ObjectMapper().readValue(classPathResource.getFile(), AdapterConfig.class); 
  11.  
  12.             return KeycloakDeploymentBuilder.build(adapterConfig); 
  13.         } 
  14.     }; 

角色命名策略

Spring Security会为每个角色添加ROLE_前缀,这需要我们声明GrantedAuthoritiesMapper的实现SimpleAuthorityMapper来完成这一功能。Keycloak在KeycloakAuthenticationProvider中配置该功能:

  1. KeycloakAuthenticationProvider authenticationProvider = keycloakAuthenticationProvider(); 
  2.  authenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper()); 

完整的配置

applicaiton.yaml:

  1. keycloak: 
  2. # 声明客户端所在的realm 
  3.   realm: felord.cn 
  4. # keycloak授权服务器的地址 
  5.   auth-server-url: http://localhost:8011/auth 
  6. # 客户端名称 
  7.   resource: springboot-client 
  8. # 声明这是一个公开的客户端,否则不能在keycloak外部环境使用,会403 
  9.   public-client: true 

这里要结合Keycloak导出的json文件配置。

Spring Security配置:

  1. @KeycloakConfiguration 
  2. public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter { 
  3.      
  4.      
  5.     @Bean 
  6.     public KeycloakConfigResolver keycloakConfigResolver() { 
  7.         return new KeycloakSpringBootConfigResolver(); 
  8.     } 
  9.      
  10. //    @Bean 
  11.     public KeycloakConfigResolver fileKeycloakConfigResolver() { 
  12.         return request -> { 
  13.             // json 文件放到resources 文件夹下 
  14.             ClassPathResource classPathResource = new ClassPathResource("./keycloak.json"); 
  15.             AdapterConfig adapterConfig = null
  16.             try { 
  17.                 adapterConfig = new ObjectMapper().readValue(classPathResource.getFile(),  
  18.                         AdapterConfig.class); 
  19.             } catch (IOException e) { 
  20.                 e.printStackTrace(); 
  21.             } 
  22.  
  23.             return KeycloakDeploymentBuilder.build(adapterConfig); 
  24.         }; 
  25.     } 
  26.      
  27.     @Autowired 
  28.     public void configureGlobal(AuthenticationManagerBuilder auth) { 
  29.         KeycloakAuthenticationProvider authenticationProvider = keycloakAuthenticationProvider(); 
  30.         authenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper()); 
  31.         auth.authenticationProvider(authenticationProvider); 
  32.     } 
  33.      
  34.     @Bean 
  35.     @Override 
  36.     protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { 
  37.         return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl()); 
  38.     } 
  39.      
  40.     @Bean 
  41.     public ServletListenerRegistrationBean httpSessionEventPublisher() { 
  42.         return new ServletListenerRegistrationBean<>(new HttpSessionEventPublisher()); 
  43.     } 
  44.     @Override 
  45.     protected void configure(HttpSecurity http) throws Exception { 
  46.         super.configure(http); 
  47.         http 
  48.                 .authorizeRequests() 
  49.                 .antMatchers("/customers*").hasRole("USER"
  50.                 .antMatchers("/admin/**").hasRole("base_user"
  51.                 .anyRequest().permitAll(); 
  52.     } 

调用流程

资源客户端springboot-client有一个接口/admin/foo,当未登录调用该接口时会转发到:

  1. http://localhost:8011/auth/realms/felord.cn/protocol/openid-connect/auth?response_type=code&client_id=springboot-client&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fsso%2Flogin&state=ec00d608-5ce7-47a0-acc8-8a20a2bfadfd&login=true&scope=openid 

输入正确的用户密码后才能得到期望的结果。

典型的authorazation code flow。

总结

Keycloak整合Spring Security的要点这里需要再梳理一下。在原生情况下,客户端的配置、用户的信息、角色信息都由Keycloak负责;客户端只负责角色和资源的映射关系。后续会深入并定制Keycloak和Spring Security以满足实际场景需要。

本文转载自微信公众号「码农小胖哥」,可以通过以下二维码关注。转载本文请联系码农小胖哥公众号。

来源:码农小胖哥内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯