自己怎样学做网站,重庆妇科医院在线咨询,情侣做记录网站源码,做房地产销售的基础知识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 独立服务器发行版。点击 这里 从官方下载。
下载完后解压缩并从终端启动 Keycloak
unzip 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
登录成功后进入控制台默认为 Master Realm。
导航到左上角找到 “Create realm” 按钮 点击它添加一个名为 SpringBootKeycloak 的新 Realm 单击 “Create” 按钮创建一个新的 Realm。会被重定向到该 Realm。接下来的所有操作都将在这个新的 SpringBootKeycloak Realm 中执行。
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 Token
Keycloak 提供了用于生成和刷新 Access Token 的 REST API可用于创建自己的登录页面。
首先向如下 URL 发送 POST 请求从 Keycloak 获取 Access Token
http://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 依赖
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-oauth2-client/artifactId
/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactId
/dependency使用 spring-boot-starter-oauth2-resource-server 将身份验证控制委托给 Keycloak 服务器。它允许我们使用 Keycloak 服务器验证 JWT Token
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-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。它可以根据 Schema spring.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、配置类
创建 SecurityFilterChain Bean 来配置 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;}Overridepublic 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、Controller
Web 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