spring boot 3.2 整合 keycloak

news2024/11/17 13:46:31

背景

项目中用到 keycloak,因此其他所有管理页面要集成 keycloak 做统一登录认证。

Keycloak 侧配置

容器方式启动 keycloak 服务端

docker run -d --name mykeycloak -p 8080:8080         -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin         keycloak         start-dev

注意如果不能联网的话需要要提前下载好镜像。

创建域

启动后,浏览器登录 http://ip:8080,默认用户名密码:admin/admin
创建域:client
在这里插入图片描述
在这里插入图片描述

创建客户端

在这里插入图片描述
打开客户端认证
在这里插入图片描述
设置登录成功后的重定向地址(这里可以添加多个)
在这里插入图片描述
获取密钥,这个在配置 spring boot 时需要
在这里插入图片描述

创建用户

这里的用户用于统一认证。
在这里插入图片描述
设置登录密码
在这里插入图片描述

Spring boot 侧实现

keycloak 有好几种方式集成 spring boot,例如(https://www.keycloak.org/docs/latest/securing_apps/index.html):
在这里插入图片描述

之前使用的是 Adapter 方式,但是官方已经废弃了,现在统一用 oauth2。

引入依赖

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>

如果没有特殊要求,则直接使用 spring boot 中配置的版本即可,不用单独设置版本。

添加 Security Filter

package casuallc.github.io;

import static casuallc.github.io.global.Constants.IGNORE_AUTHENTICATION_RESOURCES;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;

@Configuration
@EnableWebSecurity
@Slf4j
public class CustomSecurityConfiguration {

    @Value("${security.enabled}")
    private boolean securityEnabled;
    @Value("${security.same-site.enabled}")
    private boolean securitySameSiteEnabled;
    @Value("${security.keycloak.enabled:false}")
    private boolean keyCloakEnabled;
    @Value("${security.oauth2.enabled:false}")
    private boolean oauth2Enabled;
    @Value("${security.oauth2.logout.url:}")
    private String oauth2LogoutUrl;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        if (!securitySameSiteEnabled) {
            http.headers(AbstractHttpConfigurer::disable);
        } else {
            http.headers(header -> header.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin));
        }

        if (securityEnabled) {
            CookieCsrfTokenRepository csrfTokenRepository = new CookieCsrfTokenRepository();
            csrfTokenRepository.setCookieCustomizer(cookie -> cookie.secure(true)
                    .maxAge(86400));
            http.csrf(csrf -> csrf.ignoringRequestMatchers(IGNORE_AUTHENTICATION_RESOURCES)
                    .csrfTokenRepository(csrfTokenRepository));
            return http.build();
        }

        // 使用其他方式认证时关闭 csrf
        http.csrf(AbstractHttpConfigurer::disable);

        if (keyCloakEnabled || oauth2Enabled) {
            http.authorizeHttpRequests(a -> a
                            .requestMatchers(IGNORE_AUTHENTICATION_RESOURCES)
                            .permitAll()
                            .anyRequest()
                            .authenticated())
                    .oauth2Login(Customizer.withDefaults());
            if (StringUtils.isNotBlank(oauth2LogoutUrl)) {
                http.logout(r -> r.logoutSuccessUrl(oauth2LogoutUrl));
            }
            log.info("{} enabled ...", keyCloakEnabled ? "Keycloak" : "Oauth2");
            return http.build();
        }

        log.info("Security CSRF disabled ...");
        return http.build();
    }
}

IGNORE_AUTHENTICATION_RESOURCES 配置了哪些请求不需要认证,比如登录地址。

添加认证配置

### --- 认证配置(需要关闭security.same-site.enabled和security.enabled) --- ###
security.keycloak.enabled=true
spring.security.oauth2.client.provider.external.issuer-uri=http://keycloak:8080/realms/test

spring.security.oauth2.client.registration.external.provider=external
# 客户端名称
spring.security.oauth2.client.registration.external.client-name=client
# 客户端名称
spring.security.oauth2.client.registration.external.client-id=client
spring.security.oauth2.client.registration.external.client-secret=配置在 keycloak client 页面获取的密钥
spring.security.oauth2.client.registration.external.scope=openid,offline_access,profile
spring.security.oauth2.client.registration.external.authorization-grant-type=authorization_code

获取登录用户

在使用 keycloak 登录后,在 request 中可以获取到用户信息

public static String getUserFromOauth2(HttpServletRequest request) {
	OAuth2AuthenticationToken token = (OAuth2AuthenticationToken) request.getUserPrincipal();
	if (token == null) {
		log.warn("Can not get keycloak user from request.");
		return null;
	}
	OAuth2User user = token.getPrincipal();
	if (user instanceof DefaultOidcUser oidcUser) {
		return oidcUser.getPreferredUsername();
	}
	if (user instanceof DefaultOAuth2User oAuth2User) {
		return oAuth2User.getName();
	}
	return user.getName();
}

最后

以上操作完成后,可以访问 spring boot 项目,会自动跳转到 keycloak 登录页面,登录成功后重定向到 spring boot 项目页面。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1295253.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python ItsDangerous库:构建安全可靠的数据传输

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com ItsDangerous是Python中一个轻量级的库&#xff0c;旨在提供安全且简单的数据传输和签名功能。本文将深入介绍ItsDangerous的核心特性、基本用法以及在实际应用中的一些示例&#xff0c;通过丰富的示例代码&…

【思路代码详解】2023mathorcup大数据复赛B题妈妈杯高校数学建模挑战赛电商零售商家需求预测及库存优化问题

2023 年 MathorCup 高校数学建模挑战赛——大数据竞赛 赛道 B复赛&#xff1a;电商零售商家需求预测及库存优化问题 问题一 目标&#xff1a;制定补货计划&#xff0c;基于预测销量。 背景&#xff1a;固定库存盘点周期NRT1, 提前期LT3天。 初始条件&#xff1a;所有商品…

Qt12.8

使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c;密码是否为…

线程池的使用及实现

使用多进程进行并发编程&#xff0c;会频繁的创建销毁进程&#xff0c;效率比较慢&#xff0c;所以引入了线程&#xff0c;线程使用复用资源的方式提高了创建销毁的效率&#xff0c;但是随着创建线程的频率进一步提高&#xff0c;开销仍然无法忽略不计了。 要想办法优化此处线…

防火墙是什么?聊聊部署Web应用防火墙的作用

数字经济时代&#xff0c;也是一个应用爆炸的时代。在享受应用带来的便利同时&#xff0c;当前却出现许多热点威胁&#xff0c;如供应链安全、零日漏洞、数据泄露等&#xff0c;都给现代化应用带来严峻挑战。有了WAF防火墙的帮助&#xff0c;就可以拦截一系列企图通过入侵系统来…

区块链如何影响数字营销的各个方面?

在过去的几年里&#xff0c;由于区块链等新技术和趋势的进步&#xff0c;数字营销领域发生了各种变化和发展。区块链是加密货币爱好者和投资者当前的流行语。然而&#xff0c;它的可能性已经超出了加密货币的世界&#xff0c;今天&#xff0c;来自不同行业的组织正在获得他们的…

目标检测器技术演进简史

引言 目标检测算法的发展已经取得了长足的进步&#xff0c;从早期的计算机视觉方法开始&#xff0c;通过深度学习达到了很高的准确度。在这篇博文中&#xff0c;我们将一起回顾一下这些算法的发展阶段以及现代目标检测系统中使用的主要方法。 我们首先回顾早期传统的目标检测…

服务器端模板注入 (SSTI) 漏洞实战与技巧,网络高级工具透明代理的几种实现方式

服务器端模板注入 (SSTI) 漏洞实战与技巧,网络高级工具透明代理的几种实现方式。 SSTI(Server-Side Template Injection)从名字可以看出即是服务器端模板注入。比如python的flask、php的thinkphp、java的spring等框架一般都采用MVC的模式,用户的输入先进入Controller控制器,…

内网渗透基础

内网 内网指的是内部局域网&#xff0c;常说的LAN&#xff08;local area network&#xff09;。常见家庭wifi网络和小型的企业网络&#xff0c;通常内部计算机直接访问路由器设备&#xff0c;路由器设备接入移动电信的光纤实现上网。 内部局域网可以通过交换机/防火墙组成多个…

华清远见嵌入式学习——QT——作业2

作业要求&#xff1a; 代码运行效果图&#xff1a; 登录失败 和 最小化 和 取消登录 登录成功 和 X号退出 代码&#xff1a; ①&#xff1a;头文件 #ifndef LOGIN_H #define LOGIN_H#include <QMainWindow> #include <QLineEdit> //行编辑器类 #include…

《深入理解计算机系统》学习笔记 - 第四课 - 机器级别的程序

Lecture 05 Machine Level Programming I Basics 机器级别的程序 文章目录 Lecture 05 Machine Level Programming I Basics 机器级别的程序intel 处理器的历史和体系结构芯片的构成AMD 公司(Advanced Micro Devices&#xff0c;先进的微型设备) C, 汇编, 机器代码定义汇编/机器…

MDK官网如何下载stm32支持包

网站&#xff1a;https://www.keil.com/demo/eval/arm.htm 1 2 3点这个下载

打造专属小程序,乔拓云模板平台助力商家抢占先机

打造专属小程序&#xff0c;乔拓云模板平台助力商家抢占先机&#xff01;该平台涵盖全行业小程序模板&#xff0c;一键复制即可上线。 想要快速创建高效实用的小程序&#xff0c;乔拓云小程序模板开发平台为您提供了解决方案&#xff01;我们为您提供一系列精心设计的小程序模板…

智汇恒星科技|控乐屋.全宅智能冠军代言来啦, 智慧家居千亿蓝海

随着5G、大数据、云计算、物联网等技术的发展&#xff0c;智能化正覆盖人们生活的方方面面&#xff0c;全屋智能的出现为“一键式”智能家居生活享受提供无限可能。近年来智能家居行业总体规模增长迅速&#xff0c;数据显示&#xff0c;2022年中国智能家居行业市场规模约为6200…

flstudio21破解汉化版2024最新水果编曲使用教程

​ 如果你一直梦想制作自己的音乐(无论是作为一名制作人还是艺术家)&#xff0c;你可能会想你出生在这个时代是你的幸运星。这个水果圈工作室和上一版之间的改进水平确实令人钦佩。这仅仅是FL Studio 21所提供的皮毛。你的音乐项目的选择真的会让你大吃一惊。你以前从未有过这…

vue3移动端脚手架(纯净,集成丰富)

概述 一个纯净的移动端框架 &#xff0c;用到了 Vue3 vuex Vite3 Vant3 sass eslint stylelint htmlhint husky commitlint axios axios-adapter VConsole 自定义全局 loading &#xff0c;自定义函数式 dialog &#xff08;api模仿微信小程序&#xff09;&#x…

选自《洛谷深入浅出进阶篇》——欧拉函数+欧拉定理+扩展欧拉定理

欧拉函数&#xff1a; 欧拉函数定义&#xff1a; 1~n中与n互质的数的个数。 比如 欧拉函数是积性函数&#xff1a;&#xff08;也就是&#xff09;当 n与m互质的时候&#xff1a; 由算术基本定理&#xff0c;我们可以设n&#xff0c;那么我们只要计算出的取值就能求出的取…

【后端学前端学习记录】学习计划

1、个人背景 写了足够久的后端了&#xff0c;常用的语言基本上都接触过&#xff0c;没有在工作中写过前端 一直想做一些前端的工作&#xff0c;但是前端技能不足加上自己审美不行&#xff0c;写出的界面总是很丑 所以一直对前端做不好&#xff0c;也没有真正下手。 2、动机 种…

C# Solidworks二次开发:选择管理器相关的API介绍

今天在讲述主要内容之前&#xff0c;先说一个不太相关的问题。 我之前在其他文章中看到有一些朋友在问为什么获取到的点位数据需要乘以1000进行单位转换&#xff0c;其实原因是这样的&#xff0c;在所有使用的API中如果没有特殊说明&#xff0c;所有的长度单位都是米&#xff…

Langchain-Chatchat大语言模型本地知识库的踩坑、部署、使用

Langchain-Chatchat的部署 Langchain-Chatchat概述实现原理 开发环境准备软件要求硬件要求 部署拉取仓库创建虚拟环境安装全部依赖初始化配置文件初始化知识库模型下载启动项目启动API服务启动Web UI服务使用对话功能知识库管理文件对话搜索引擎问答 异常集合异常1异常2异常3 L…