Java数据库应用原型

news/2025/10/29 15:43:15/文章来源:https://www.cnblogs.com/icodewalker/p/19174604

这是一个Java 数据库应用原型,使用 Spring Boot 和容器进行测试、Keycloak 提供安全、PostgreSQL 提供数据持久化的,带有 REST 和安全功能。

在工作中开发时,我多次需要一个简单应用的模板,以便基于此模板开始为手头的项目添加特定代码。
在本文中,我将创建一个简单的 Java 应用程序,它连接到数据库,暴露一些 REST 端点,并使用基于角色的访问来保护这些端点。
目的是拥有一个最小化且功能齐全的应用程序,然后可以针对特定任务进行定制。
对于数据库,我们将使用 PostgreSQL;对于安全,我们将使用 Keycloak,两者都通过容器部署。在开发过程中,我使用 podman 来测试容器是否正确创建(作为 docker 的替代品——它们在大多数情况下可以互换)作为一次学习体验。
应用程序本身是使用 Spring Boot 框架开发的,并使用 Flyway 进行数据库版本管理。
所有这些技术都是 Java EE 领域业界标准,在项目中被使用的可能性很高。

我们构建原型的核心需求是一个图书馆应用程序,它暴露 REST 端点,允许创建作者、书籍以及它们之间的关系。这将使我们能够实现一个多对多关系,然后可以将其扩展用于任何可以想象的目的。
完整可用的应用程序可以在 https://github.com/ghalldev/db_proto 找到。
本文中的代码片段取自该代码库

在创建容器之前,请确保使用您偏好的值定义以下环境变量(教程中故意省略了它们,以避免传播多个用户使用的默认值):

DOCKER_POSTGRES_PASSWORD
DOCKER_KEYCLOAK_ADMIN_PASSWORD
DOCKER_GH_USER1_PASSWORD

配置 PostgreSQL:

docker container create --name gh_postgres --env POSTGRES_PASSWORD=$DOCKER_POSTGRES_PASSWORD --env POSTGRES_USER=gh_pguser --env POSTGRES_INITDB_ARGS=--auth=scram-sha-256 --publish 5432:5432 postgres:17.5-alpine3.22
docker container start gh_postgres

配置 Keycloak:
首先是容器的创建并启动:

docker container create --name gh_keycloak --env DOCKER_GH_USER1_PASSWORD=$DOCKER_GH_USER1_PASSWORD --env KC_BOOTSTRAP_ADMIN_USERNAME=gh_admin --env KC_BOOTSTRAP_ADMIN_PASSWORD=$DOCKER_KEYCLOAK_ADMIN_PASSWORD --publish 8080:8080 --publish 8443:8443 --publish 9000:9000 keycloak/keycloak:26.3 start-dev
docker container start gh_keycloak

在容器启动并运行后,我们可以继续创建领域、用户和角色(这些命令必须在正在运行的容器内部执行):

cd $HOME/bin
./kcadm.sh config credentials --server http://localhost:8080 --realm master --user gh_admin --password $KC_BOOTSTRAP_ADMIN_PASSWORD
./kcadm.sh create realms -s realm=gh_realm -s enabled=true
./kcadm.sh create users -s username=gh_user1 -s email="gh_user1@email.com" -s firstName="gh_user1firstName" -s lastName="gh_user1lastName" -s emailVerified=true -s enabled=true -r gh_realm
./kcadm.sh set-password -r gh_realm --username gh_user1 --new-password $DOCKER_GH_USER1_PASSWORD
./kcadm.sh create roles -r gh_realm -s name=viewer -s 'description=Realm role to be used for read-only features'
./kcadm.sh add-roles --uusername gh_user1 --rolename viewer -r gh_realm
./kcadm.sh create roles -r gh_realm -s name=creator -s 'description=Realm role to be used for create/update features'
./kcadm.sh add-roles --uusername gh_user1 --rolename creator -r gh_realm
ID_ACCOUNT_CONSOLE=$(./kcadm.sh get clients -r gh_realm --fields id,clientId | grep -B 1 '"clientId" : "account-console"' | grep -oP '[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}')
./kcadm.sh update clients/$ID_ACCOUNT_CONSOLE -r gh_realm -s 'fullScopeAllowed=true' -s 'directAccessGrantsEnabled=true'

用户 gh_user1 在领域 gh_realm 中被创建,并拥有 viewercreator 角色。

您可能已经注意到,我们没有创建新的客户端,而是使用了 Keycloak 自带的一个默认客户端:account-console。这是为了方便起见,在实际场景中,您会创建一个特定的客户端,然后将其更新为具有 fullScopeAllowed(这会导致领域角色被添加到令牌中——默认情况下不添加)和 directAccessGrantsEnabled(允许通过 Keycloak 的 openid-connect/token 端点生成令牌,在我们的例子中使用 curl)。

创建的角色随后可以在 Java 应用程序内部使用,以根据我们约定的契约来限制对某些功能的访问——viewer 只能访问只读操作,而 creator 可以执行创建、更新和删除操作。当然,同样地,可以根据任何原因创建各种角色,只要约定的契约被明确定义并被所有人理解。
角色还可以进一步添加到组中,但本教程不包含这部分内容。

但是,在实际使用这些角色之前,我们必须告诉 Java 应用程序如何提取角色——这是必须的,因为 Keycloak 将角色添加到 JWT 的方式是其特有的,所以我们必须编写一段自定义代码,将其转换为 Spring Security 可以使用的东西:

@Bean
public JwtAuthenticationConverter jwtAuthenticationConverter() {// 遵循与 org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter 相同的模式Converter<Jwt, Collection<GrantedAuthority>> keycloakRolesConverter = new Converter<>() {private static final String DEFAULT_AUTHORITY_PREFIX = "ROLE_";//https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java#L901private static final String KEYCLOAK_REALM_ACCESS_CLAIM_NAME = "realm_access";private static final String KEYCLOAK_REALM_ACCESS_ROLES = "roles";@Overridepublic Collection<GrantedAuthority> convert(Jwt source) {Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>();Map<String, List<String>> realmAccess = source.getClaim(KEYCLOAK_REALM_ACCESS_CLAIM_NAME);if (realmAccess == null) {logger.warn("No " + KEYCLOAK_REALM_ACCESS_CLAIM_NAME + " present in the JWT");return grantedAuthorities;}List<String> roles = realmAccess.get(KEYCLOAK_REALM_ACCESS_ROLES);if (roles == null) {logger.warn("No " + KEYCLOAK_REALM_ACCESS_ROLES + " present in the JWT");return grantedAuthorities;}roles.forEach(role -> grantedAuthorities.add(new SimpleGrantedAuthority(DEFAULT_AUTHORITY_PREFIX + role)));return grantedAuthorities;}};JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(keycloakRolesConverter);return jwtAuthenticationConverter;
}

AppConfiguration 类中还完成了其他重要配置,例如启用方法安全性和禁用 CSRF。

现在我们可以在 REST 控制器中使用 @org.springframework.security.access.prepost.PreAuthorize 注解来限制访问:

@PostMapping("/author")
@PreAuthorize("hasRole('creator')")
public void addAuthor(@RequestParam String name, @RequestParam String address) {authorService.add(new AuthorDto(name, address));
}@GetMapping("/author")
@PreAuthorize("hasRole('viewer')")
public String getAuthors() {return authorService.allInfo();
}

通过这种方式,只有成功通过身份验证且拥有 hasRole 中列出的角色的用户才能调用端点,否则他们将收到 HTTP 403 Forbidden 错误。

在容器启动并配置完成后,Java 应用程序可以启动了,但在启动之前需要添加数据库密码——这可以通过环境变量完成(下面是一个 Linux shell 示例):

export SPRING_DATASOURCE_PASSWORD=$DOCKER_POSTGRES_PASSWORD

现在,如果一切正常启动并运行,我们可以使用 curl 来测试我们的应用程序(以下所有命令均为 Linux shell 命令)。

使用之前创建的用户 gh_user1 登录并提取身份验证令牌:

KEYCLOAK_ACCESS_TOKEN=$(curl -d 'client_id=account-console' -d 'username=gh_user1' -d "password=$DOCKER_GH_USER1_PASSWORD" -d 'grant_type=password' 'http://localhost:8080/realms/gh_realm/protocol/openid-connect/token' | grep -oP '"access_token":"\K[^"]*')

创建一个新作者(这将测试 creator 角色是否有效):

curl -X POST --data-raw 'name="GH_name1"&address="GH_address1"' -H "Authorization: Bearer $KEYCLOAK_ACCESS_TOKEN" 'localhost:8090/library/author'

检索库中的所有作者(这将测试 viewer 角色是否有效):

curl -X GET -H "Authorization: Bearer $KEYCLOAK_ACCESS_TOKEN" 'localhost:8090/library/author'

至此,您应该拥有了创建自己的 Java 应用程序所需的一切,可以根据需要对其进行扩展和配置。


【注】本文译自:Java Spring Boot Template With PostgreSQL, Keycloak Securit

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

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

相关文章

2025:智能体元年|国内智能体培训机构优劣势对比

2025年,AI智能体(AI Agent)迎来了真正的“元年”。 越来越多的人和我一样,对智能体充满了兴趣和好奇。 但面对市场上层出不穷的“智能体培训机构”,到底该怎么选?为了让大家少走弯路,我整理并对比了国内目前几家…

2025 年注塑机定制厂家最新推荐榜,技术实力与市场口碑深度解析,甄选高精度节能优质品牌专用注塑机/瓶盖专用注塑机/电动工具专用注塑机公司推荐

引言 2025 年注塑机行业竞争愈发激烈,为助力企业精准选择适配设备,塑料机械工业协会联合行业权威测评机构,开展了为期 3 个月的注塑机品牌综合测评。测评采用 “三维九项” 评估体系,从技术实力(精度控制、节能效…

2025年小红书代运营/营销/推广/种草/探店推荐榜:广州布马五星领跑!全链路种草 + 数据转化,另2家公司凭垂类 / 联动 / 性价比显实力

随着 2025 年品牌对 “小红书内容种草 - 流量转化” 闭环需求的升级,专业小红书代运营成为中小品牌快速抢占平台流量、降低试错成本的关键选择。综合服务完整性、种草效果、转化能力及用户反馈,小红书代运营公司推荐…

MySQL统计分析binlog的数量与大小

MySQL统计分析binlog的数量与大小2025-10-29 15:38 潇湘隐者 阅读(0) 评论(0) 收藏 举报脚本介绍 脚本mysql_binlog_gen_sum.sh/mysql_binlog_gen_sum的功能与用途如下所示:按天统计MySQL的binlog的生成数量(个数)…

从案例看网站建设价值:卓越迈创如何适配企业多元化需求,深圳外贸网站建设公司,深圳企业网站建设公司推荐

数字化转型加速背景下,网站建设已成为企业构建核心竞争力的重要环节,如何找到适配自身需求的网站建设解决方案成为众多企业的共同诉求。深圳市卓越迈创网络科技有限公司作为深耕该领域的服务商,其基于不同行业场景的…

多功能视频处理工具:轻松搞定提音频、转 GIF、截图与合并

日常处理视频时,你是否常遇到这些需求:想提取片段中的背景音乐、将精彩瞬间转成 GIF 动图、截取高清帧作为素材,或是拼接多个视频片段?这款小巧实用的视频处理工具,正是为解决这些场景而生。 程序整合了音频提取、…

Resource和AutoWired区别

一、区别 1、来源不同 2、依赖查找顺序不同 3、支持参数不同 4、依赖注入用法不同 二、具体内容 1、来源不同 Resource由Java标准(JSR-250)提供,属于javax.annotation包,不依赖Spring框架,具有更高可移植性,适用…

sg.time 详解

在 PySimpleGUI 中,sg.time 模块主要涉及时间管理功能,核心包括时间获取、计时器控制及线程协作,以下为详细说明: 1. 时间获取:sg.time.time()功能:获取当前 Unix 时间戳(从 1970 年 1 月 1 日 UTC 开始的秒数,…

更新Vben5登录页的背景svg

在apps/web-antd/src/layouts/auth.vue文件添加slogan-image属性为图片png等格式,svg不行<AuthPageLayout:app-name="appName":logo="logo"slogan-image="/login-banner.png":page-…

2025年斗式输送机生产商权威推荐榜单:链斗输送机/z型输送机/c型输送机源头生产商精选

斗式输送机作为建材、化工、粮食、矿山等行业物料输送系统的核心设备,其性能直接关系到生产线的效率和稳定性。据行业统计,2024年我国输送机械市场规模已达350亿元,年均增长率稳定在7%-9%之间。 在众多工业应用中,…

[CSP-S 2021] 括号序列 题解

SolutionLink 对区间 DP 的理解加深了! 常规地,我们设 \(f_{l, r}\) 表示区间 \([l, r]\) 为合法序列的方案数,并从小到大转移。这些内容不太够我们转移啊,而且由于合并顺序的不同还会出现重复的情况: \[\begin{a…

游戏战斗服随记

一 . 常规跨服玩法对服务器的需求 ​ 服务器的需求:负载均衡,固定路由算法,rpc异步消息中间件中转服务器gof(直连)二 . 战斗玩法对服务器的需求 服务器的战斗选择:帧同步和状态同步都可以实现雷神的战斗,选择帧…

2025年阻燃输送带生产厂家权威推荐榜单:尼龙输送带/三叶输送带/输送带源头厂家精选

阻燃输送带作为矿山、电力、化工等行业的安全生产关键设备,其质量直接关系到生产安全与运营效率。据行业统计,2024年我国阻燃输送带市场规模已达85亿元,年均增长率稳定在8%-10%之间。 在煤矿等高危环境,符合国家阻…

详细介绍:数据驱动AI实战:从统计学习方法到业务落地的核心方法论

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025年水平桥架源头厂家排行榜前十强

文章摘要 水平桥架作为电缆管理系统的关键组件,随着建筑和基础设施行业的快速发展,市场需求持续增长。2025年,行业将更加注重产品质量、服务效率和源头厂家的可靠性。本文基于权威数据和市场调研,为您呈现水平桥架…

2025年水平桥架供应厂家推荐榜:顶级品牌盘点

文章摘要 水平桥架行业在2025年持续蓬勃发展,随着智能城市和基础设施升级的推进,市场需求显著增长。根据行业数据,中国桥架市场规模预计年复合增长率达8%,西南地区成为重点发展区域。本文提供一份权威的水平桥架供…

2025年水平桥架公司 top 10 权威推荐

摘要 水平桥架行业在2025年预计将持续增长,受益于基础设施建设和智能建筑趋势,市场需求旺盛。本文基于行业数据和用户口碑,整理出水平桥架公司 top 10 排名榜单,为工程采购和决策提供参考。榜单包括品牌介绍、核心…

Transformers

Transformers https://huggingface.co/docs/transformers/main/indexTransformers acts as the model-definition framework for state-of-the-art machine learning models in text, computer vision, audio, video, …

macOS 终端配置全攻略:zsh、bash_profile、zprofile、zshrc 到 nvm 安装的完整科普

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025年口碑好的冲孔铝单板公司排名前十推荐

文章摘要 冲孔铝单板作为建筑幕墙和室内装饰的重要材料,2025年行业预计保持10%年增长率,得益于绿色建筑政策和城市化进程。本文基于市场调研、用户评价和行业数据,精选出口碑好的冲孔铝单板公司排名,旨在为工程商、…