Keycloak 是 RedHat 的开源身份和访问管理解决方案, 本文介绍如何在我们的微服务安全模块中使用 keycloak, 特别是基于 SpringBoot 的微服务.
Keycloak
它提供了身份和访问管理的有用功能:
单点登录 (SSO), 身份代理和社交登录
用户联合
客户端适配器
管理控制台和帐户管理控制台.
虽然安全性是任何应用程序的一个重要方面, 但安全性的实现部分是复杂和困难的. 通常, 它在代码中经常被忽略或执行不当和干扰.
开发人员需要安全服务器, 允许外包和授权认证和授权方面. 他们想要一种能够自动开发应用程序安全功能的工具, 这通常是一项复杂的任务.
Keycloak 是最有前途的开源 IDAM(身份和访问管理) 服务器之一, 它与任何技术无关, 可以在自己的基础架构中轻松部署 / 适应.
Keycloak 尝试解决基于 REST 的 web 应用程序和 Web 服务的单点登录. Keycloak 的最终目标是使安全性足够简单, 以便作为服务和应用程序中的安全模块插入. 安全功能很混乱, 当开发人员手动为自己编写时, 它会变得更危险, 更容易出错. Keycloak 通过提供开箱即用的安全功能帮助我们, 并且可以根据任何组织的个性化需求轻松定制.
Keycloak 可以帮助我们在应用程序中引入这些功能:
用于登录, 注册, 管理和帐户管理的可自定义用户界面
集成到现有 LDAP 和活动目录服务器
将身份验证委托给 Twitter 和 GitHub 等第三方身份提供商
安装:
有不同的方法来安装 keycloak. 最简单的是只需下载 Keycloak, 这是一种独立的安装模式, 只需将其解压缩即可. 你完成了! 现在打开一个终端并转到解压缩的 Keycloak 服务器并导航到 bin 目录 - 然后只需运行以下命令:
./standalone.sh(bat)
安装完成后, 打开浏览器并转到 http:// localhost:8080 / auth.
默认情况下, Keycloak 附带一个 H2 数据库, 但如果你选择 RDMS, 你可以使用带有 RDMS 的 Keycloak.
由于您是第一次运行服务器, 因此您必须创建管理员用户. 让我们创建一个管理员用户, 其中 "admin" 作为用户名,"admin" 作为密码.
创造一个新领域
在 Keycloak 中, 领域是您定义客户端的地方. 这意味着这些客户端是将由 Keycloak 保护的应用程序 - 可能是 Web 应用程序或 Spring Boot.
注意:'Master'是 Keycloak 的默认领域. 让我们只需点击 "添加领域" 按钮即可创建新领域
创建客户端
Spring Boot 应用程序是您的客户端. 就这么简单. 在 Keycloak 中, 客户端是使用 Keycloak 保护的应用程序.
让我们看看如何在 Keycloak 中创建客户端:
转到门户网站中的 "Client" 菜单
单击 "创建" 按钮
为 Client-Id 提供名称. 我们称之为 Rbi-Service.
在下一个屏幕上将所有内容保持为默认值, 您需要的只是输入一个有效的重定向 URL,Keycloak 将在该应用程序中对用户进行身份验证时使用该 URL. 我们将选择在有效的重定向 URL 部分中保留 http:// localhost:8081/*.
Keycloak API:
您现在可能正在使用当前项目中的 REST API. 别担心, Keycloak 提供对 REST API 的完全支持. 实际上, 它还提供了一个完整的管理控制台, 可以通过 REST API 使用.
这是可能的 Keycloak 管理 REST API 列表.
对于管理 REST API, 有一个 Java 客户端库, 可以很容易地与 Java 一起使用. 要从您的应用程序中使用它 - 就像您对任何第三方库所做的那样 - 只需在项目中添加 keycloak-admin-client 库的依赖项. 而已.
- <dependency>
- <groupId>org.keycloak</groupId>
- <artifactId>keycloak-admin-client</artifactId>
- <version>3.2.1.Final</version>
- </dependency>
application.YAML 配置:
- server:
- port: 9999
- keycloak:
- url: http://localhost:8080/auth
- realm: master
- username: admin
- password: admin
- clientId: admin-cli
注意: 我们需要 clientId 作为 admin-cli, 这由 keycloak 提供的所有默认客户端 ID, 用于实现 keycloak 为 admin 提供的 REST 端点,
REST API 实现
使用 REST 端点在域中创建用户有几个步骤:
1. 创建用户:
第 1 步: 通过 getInstance() 方法使用主管理员的详细信息创建实例
Keycloak kcMaster = Keycloak.getInstance(serverUrl, masterRealm, masterUsername, masterPassword, masterClientId);
第 2 步: 在 UserRepresentation 中设置用户数据
- private String userName;
- private String firstName;
- private String lastName;
- private String email;
- private String password;
- private String companyName;
密码映射到 CredentialRepresentation. 您必须强制用户在首次登录时通过以下代码更改密码:
- credential.setTemporary(isTempPassword);
- and user.setRequiredActions(Arrays.asList(ACTION_UPDATE_PASSWORD));
最后, 您所要做的就是在给定领域中调用 createUser:
kcMaster.realm(request.getCompanyName()).users().create(user);
由于 Keycloak 拥有自己的数据库, 因此新创建的用户信息存储在表中: user_entity
恭喜! 您刚刚使用 REST 端点在 Keyclaok 中创建了一个用户.
2. 用户登录访问和刷新令牌
现在遇到一个重大挑战: 将用户登录到您的应用程序中
Keycloak 根据您在 Keycloak 中配置客户端的方式提供了几种获取访问令牌的方法. Keycloak 为您提供 AccessTokenResponse, 它是一个基于 JWT 的令牌, 包含访问令牌, 刷新令牌和这些属性的相关信息.
- @PostMapping(path = "/login", consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE)
- public AccessTokenResponse getToken(@RequestBody Map<String, Object> credentials) {
- Keycloak kc = Keycloak.getInstance(serverUrl,
- (String credentials.get("company"),
- (String) credentials.get("username"),
- (String) credentials.get("password"),
- (String) credentials.get("clientId"));
- return kc.tokenManager().getAccessToken();
- }
您可以重新检查详细数据, 该数据嵌入了 jwt.io 上的访问令牌
Keycloak with Spring
Keycloak 知道自己的 API 与应用程序的交互, 并为愿意与 Keycloak 通信的应用程序提供适配器. 它已经为 JavaScript,Node.JS 应用程序, WildFly / EAP 和 Spring Boot 提供了适配器. Spring-boot 的 keycloak 依赖 (源代码)
关于安全配置:
如果您是后端开发人员而且您正在使用 Spring, 并且您必须处理与安全相关的任务, 那么您肯定使用 Spring Security. 好吧, 有一个好消息: 有一个 Keycloak Spring 安全适配器, 它包含在 Spring Boot keycloak starter 中.
如果您使用过 Spring Security, 那么您可能知道 SecurityConfig 类扩展了 WebSecurityConfigurerAdapter. 这是为创建 WebSecurityConfigurer 实例提供了方便的基类, 并且任何使用 Spring Security 的应用程序都需要它. Keycloak 在 WebSecurityConfigurerAdapter 上提供了一个包装类, 名为 KeycloakWebSecurityConfigurerAdapter.
现在让我们看看如何将 Spring Security 和 Keycloak 结合在一起.
添加 Spring Security Starter
首先, 我们需要在 pom.xml 中添加 spring-boot-starter-security 工件来获取 Spring Security 库:
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-security</artifactId>
- </dependency>
创建 SecurityConfig 类
- @Configuration
- @EnableWebSecurity
- @ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
- public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
- @Autowired
- public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
- KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
- keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
- auth.authenticationProvider(keycloakAuthenticationProvider);
- }
- @Bean
- public KeycloakConfigResolver KeycloakConfigResolver() {
- return new KeycloakSpringBootConfigResolver();
- }
- @Bean
- @Override
- protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
- return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
- }
- @Override
- protected void configure(HttpSecurity http) throws Exception
- {
- super.configure(http);
- http
- .authorizeRequests()
- .antMatchers("/features*").hasRole("user")
- .anyRequest().permitAll();
- }
- }
让我们仔细看看最重要的方法:
configureGlobal: 如果你还记得 Spring Security, 那么角色的前缀是 ROLE_. 这也可以在 keycloak 中完成, 但这可能会导致其他应用程序不知道此约定的混淆. 通过更改授权机构映射器, 我们分配一个 SimpleAuthorityMapper, 确保不添加前缀.
keycloakConfigResolver: 默认情况下, Keycloak Spring Security Adapter 将扫描类路径中存在的名为 keycloak.JSON 的文件. 在这里, 我们要提供 Spring Boot 属性文件支持.
configure: 这是我们定义安全验证的地方. 很容易理解我们正在使用角色 "user" 保护路径 "/ features".
结论
在您的应用程序中构建安全组件总是很困难, 特别是当它是基于微服务的架构时. 当然有多种选择可用于构建安全服务, 但 Keycloak 承担这一责任并帮助开发人员专注于产品或应用程序所需的内容.
由于 Keycloak 中的每个组件都经过了很好的尝试和测试, 因此在安全模块方面遇到任何麻烦的可能性都很小.
Keycloak 确实为 Spring 开发人员提供了处理安全性的巨大潜力, 特别是在开发正朝着构建微服务战略的方向发展时.
来源: http://www.bubuko.com/infodetail-2996448.html