2026/2/15 5:08:39
网站建设
项目流程
网站后台是怎么做的,wordpress 仪表盘 渗透,全国八大员报名官方网站,南京网站建设 雷仁网络1、概览
本文将带你了解如何设置 Keycloak 服务器#xff0c;以及如何使用 Spring Security OAuth2.0 将Spring Boot应用连接到 Keycloak 服务器。
2、Keycloak 是什么#xff1f;
Keycloak是针对现代应用和服务的开源身份和访问管理解决方案。
Keycloak 提供了诸如单点登…1、概览本文将带你了解如何设置 Keycloak 服务器以及如何使用 Spring Security OAuth2.0 将Spring Boot应用连接到 Keycloak 服务器。2、Keycloak 是什么Keycloak是针对现代应用和服务的开源身份和访问管理解决方案。Keycloak 提供了诸如单点登录SSO、身份代理和社交登录、用户联盟、客户端适配器、管理控制台和账户管理等功能。本文使用 Keycloak 的管理控制台使用 Spring Security OAuth2.0 设置和连接 Spring Boot。3、设置 Keycloak 服务器设置和配置 Keycloak 服务器。3.1、下载和安装 Keycloak有多种发行版可供选择本文使 Keycloak-22.0.3 独立服务器发行版。点击这里从官方下载。下载完后解压缩并从终端启动 Keycloakunzip keycloak-22.0.3.zip cd keycloak-22.0.3 bin/kc.sh start-dev运行这些命令后Keycloak 会启动服务。如果你看到一行类似于Keycloak 22.0.3 [...] started的内容就表示服务器启动成功。打开浏览器访问http://localhost:8080会被重定向到http://localhost:8080/auth以创建管理员进行登录创建一个名为initial1的初始管理员用户密码为zaq1!QAZ。点击 “Create”后可以看到 “User Created” 的提示信息。现在进入管理控制台。在登录页面输入initial管理员用户凭证3.2、创建 Realm登录成功后进入控制台默认为MasterRealm。导航到左上角找到 “Create realm” 按钮点击它添加一个名为SpringBootKeycloak的新 Realm单击 “Create” 按钮创建一个新的 Realm。会被重定向到该 Realm。接下来的所有操作都将在这个新的SpringBootKeycloakRealm 中执行。3.3、创建客户端现在进入 “Clients” 页面。如下图所示Keycloak 已经内置了客户端我们需要在应用中添加一个新客户端点击 “Create”将新客户端命名为login-app在下一步的设置中除了 “Valid Redirect URIs” 字段外其他字段保留所有默认值。该字段包含将使用此客户端进行身份验证的应用 URL稍后我们会创建一个运行于 8081 端口的 Spring Boot 应用该应用将使用该客户端。因此在上面使用了http://localhost:8081/的重定向 URL。3.4、创建角色和用户Keycloak 使用基于角色的访问因此每个用户都必须有一个角色。进入 “Realm Roles” 页面然后添加用户角色现在有了一个可以分配给用户的角色但由于还没有用户让我们去 “Users” 页面添加一个添加一个名为user1的用户用户创建后会显示一个包含其详细信息的页面现在进入 “Credentials” 选项卡。把初始密码设置为xsw2WS最后进入 “Role Mappings” 选项卡。为user1分配用户角色4、使用 Keycloak API 生成 Access TokenKeycloak 提供了用于生成和刷新 Access Token 的 REST API可用于创建自己的登录页面。首先向如下 URL 发送 POST 请求从 Keycloak 获取 Access Tokenhttp://localhost:8080/realms/SpringBootKeycloak/protocol/openid-connect/token请求体应包含x-www-form-urlencoded格式的参数client_id:your_client_id username:your_username password:your_password grant_type:password这会得到一个access_token和一个refresh_token。每次请求受 Keycloak 保护的资源时都应使用 Access Token只需将其放在Authorization头中即可headers: { Authorization: Bearer access_token }Access Token 过期后可以通过向上述相同的 URL 发送 POST 请求来刷新 Access Token但请求中应包含 Refresh Token而不是用户名和密码{ client_id: your_client_id, refresh_token: refresh_token_from_previous_request, grant_type: refresh_token }Keycloak 会响应新的access_token和refresh_token。5、创建和配置 Spring Boot 应用创建一个 Spring Boot 应用并将其配置为 OAuth 客户端与 Keycloak 服务器进行交互。5.1、依赖使用 Spring Security OAuth2.0 客户端连接到 Keycloak 服务器。首先在pom.xml中声明spring-boot-starter-oauth2-client和spring-boot-starter-security依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-oauth2-client/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-security/artifactId /dependency使用spring-boot-starter-oauth2-resource-server将身份验证控制委托给 Keycloak 服务器。它允许我们使用 Keycloak 服务器验证 JWT Tokendependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-oauth2-resource-server/artifactId /dependency现在Spring Boot 应用可以与 Keycloak 交互了。5.2、Keycloak 配置将 Keycloak 客户端视为 OAuth 客户端。因此需要配置 Spring Boot 应用以使用 OAuth 客户端。ClientRegistration类保存客户端的所有基本信息。Spring 自动配置会查找模式为spring.security.oauth2.client.registration.[registrationId]的属性并使用 OAuth 2.0 或 OpenID ConnectOIDC 注册客户端。客户端注册配置spring.security.oauth2.client.registration.keycloak.client-idlogin-app spring.security.oauth2.client.registration.keycloak.authorization-grant-typeauthorization_code spring.security.oauth2.client.registration.keycloak.scopeopenid在client-id中指定的值与我们在管理控制台中命名的客户端相匹配。Spring Boot 应用需要与 OAuth 2.0 或 OIDC Provider 交互以处理不同授权方式的实际请求逻辑。因此需要配置 OIDC Provider。它可以根据 Schemaspring.security.oauth2.client.provider.[provider name]的属性值自动配置。OIDC Provider 配置spring.security.oauth2.client.provider.keycloak.issuer-urihttp://localhost:8080/realms/SpringBootKeycloak spring.security.oauth2.client.provider.keycloak.user-name-attributepreferred_username在issuer-uri中指定路径我们是在 8080 端口启动 Keycloak 的。该属性标识了授权服务器的基本 URI输入在 Keycloak 管理控制台中创建的 Realm 名称。此外还可以将user-name-attribute定义为preferred_username以便在 Controller 的Principal中填充合适的用户。最后添加针对 Keycloak 服务器验证 JWT Token 所需的配置spring.security.oauth2.resourceserver.jwt.issuer-urihttp://localhost:8080/realms/SpringBootKeycloak5.3、配置类创建SecurityFilterChainBean 来配置HttpSecurity。使用http.oauth2Login()启用 OAuth2 登录。创建 Security 配置Configuration EnableWebSecurity class SecurityConfig { private final KeycloakLogoutHandler keycloakLogoutHandler; SecurityConfig(KeycloakLogoutHandler keycloakLogoutHandler) { this.keycloakLogoutHandler keycloakLogoutHandler; } Bean protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl()); } Order(1) Bean public SecurityFilterChain clientFilterChain(HttpSecurity http) throws Exception { http.authorizeRequests() .requestMatchers(new AntPathRequestMatcher(/)) .permitAll() .anyRequest() .authenticated(); http.oauth2Login() .and() .logout() .addLogoutHandler(keycloakLogoutHandler) .logoutSuccessUrl(/); return http.build(); } Order(2) Bean public SecurityFilterChain resourceServerFilterChain(HttpSecurity http) throws Exception { http.authorizeRequests() .requestMatchers(new AntPathRequestMatcher(/customers*)) .hasRole(USER) .anyRequest() .authenticated(); http.oauth2ResourceServer((oauth2) - oauth2.jwt(Customizer.withDefaults())); return http.build(); } Bean public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception { return http.getSharedObject(AuthenticationManagerBuilder.class) .build(); } }在上面的代码中oauth2Login()方法将OAuth2LoginAuthenticationFilter添加到过滤器链中。该过滤器会拦截请求并应用 OAuth 2 身份验证所需的逻辑。oauth2ResourceServer方法将根据 Keycloak 服务器验证绑定的 JWT Token。在configure()方法中根据权限和角色配置访问权限。这些约束条件可确保对/customers/*的每个请求只有在请求者是具有USER角色的经过身份验证的用户时才会获得授权。最后添加了KeycloakLogoutHandler类来处理 Keycloak 注销Component public class KeycloakLogoutHandler implements LogoutHandler { private static final Logger logger LoggerFactory.getLogger(KeycloakLogoutHandler.class); private final RestTemplate restTemplate; public KeycloakLogoutHandler(RestTemplate restTemplate) { this.restTemplate restTemplate; } Override public void logout(HttpServletRequest request, HttpServletResponse response, Authentication auth) { logoutFromKeycloak((OidcUser) auth.getPrincipal()); } private void logoutFromKeycloak(OidcUser user) { String endSessionEndpoint user.getIssuer() /protocol/openid-connect/logout; UriComponentsBuilder builder UriComponentsBuilder .fromUriString(endSessionEndpoint) .queryParam(id_token_hint, user.getIdToken().getTokenValue()); ResponseEntityString logoutResponse restTemplate.getForEntity( builder.toUriString(), String.class); if (logoutResponse.getStatusCode().is2xxSuccessful()) { logger.info(Successfulley logged out from Keycloak); } else { logger.error(Could not propagate logout to Keycloak); } } }KeycloakLogoutHandler类实现了LogoutHandler并向 Keycloak 发送注销请求。现在通过身份验证后就可以访问内部 customers 页面了。5.4、Thymeleaf Web 页面使用 Thymeleaf 渲染页面。有三个页面external.html- 面向外部的页面customers.html- 面向内部的页面其访问权限仅限于具有user角色的认证用户layout.html- 一个简单的布局由两个片段组成分别用于面向外部的页面和面向内部的页面Thymeleaf 模板的代码可在Github上获取。5.5、ControllerWeb Controller 会将内部和外部 URL 映射到相应的 Thymeleaf 模板GetMapping(path /) public String index() { return external; } GetMapping(path /customers) public String customers(Principal principal, Model model) { addCustomers(); model.addAttribute(customers, customerDAO.findAll()); model.addAttribute(username, principal.getName()); return customers; }/customers会从 Repository 中检索所有客户并将结果作为属性添加到 Model 中。之后在 Thymeleaf 中遍历结果。为了能够显示用户名还注入了Principal。注意这里只是将客户customers作为原始数据来显示仅此而已。6、演示现在测试应用。通过集成开发环境如 Spring Tool Suite - STS运行 Spring Boot 应用或者在终端运行如下命令mvn clean spring-boot:run访问http://localhost:8081如下现在点击 “customers” 户进入内部页面这是敏感信息的位置。然后会被重定向到通过 Keycloak 进行身份验证以检查我们是否被授权查看此内容用user1的凭证登录Keycloak 会验证我们的授权确认我们拥有用户角色然后会被重定向到受限的 “customers” 页面现在整个流程已经完毕了。你可以看到Spring Boot 无缝地处理了调用 Keycloak 授权服务器的整个过程。我们无需调用 Keycloak API 自己生成 Access Token甚至无需在请求受保护资源时明确发送Authorization头。7、总结本文介绍了如何如何设置了 Keycloak 服务器以及如何在 Spring Boot 中使用 Spring Security OAuth2.0 结合 Keycloak 实现认证和授权。Refhttps://www.baeldung.com/spring-boot-keycloak