javascript
使用PostgreSQL使用Spring Boot和JPA构建基本应用
“我喜歡編寫身份驗證和授權代碼。” ?從來沒有Java開發人員。 厭倦了一次又一次地建立相同的登錄屏幕? 嘗試使用Okta API進行托管身份驗證,授權和多因素身份驗證。
每個不平凡的應用程序都需要一種保存和更新數據的方法:可通過HTTP訪問的資源服務器。 通常,必須保護此數據。 Java是一門偉大的語言,在專業,企業開發方面已有數十年的歷史,對于任何應用程序的服務器堆棧都是絕佳的選擇。 在Java生態系統內,Spring使為數據構建安全的資源服務器變得簡單。 與Okta結合使用時,您可以使用Spring Security將經過專業維護的OAuth和JWT技術輕松集成到Spring Boot中。
在本文中,您將使用Spring Boot和Spring Data JPA構建資源服務器。 最重要的是,您將使用OAuth 2.0實現基于組的身份驗證和授權層。 如果這聽起來很復雜–不用擔心! 不是。
在深入探討之前,讓我們介紹一下背景知識:
資源服務器是服務器功能和數據的編程訪問點(與API服務器和/或REST服務器基本相同)。
JPA是Java Persistence API,它是使用Java管理關系數據庫的規范。 它描述了Java類和關系數據庫之間的抽象層。
Spring Data JPA是JPA提供程序(例如Hibernate)的包裝。 正如您將看到的,它使持久化Java類就像添加一些注釋和創??建簡單的存儲庫接口一樣簡單。 無需實際編寫持久性或檢索方法! 另一個很大的好處是您可以透明地更改基礎數據庫實現,而不必更改任何代碼。 例如,在本教程中,您將使用Postgres,但稍后,如果您決定使用MySQL,您要做的就是更改一些依賴項。
安裝PostgreSQL以實現JPA持久性
您需要為此教程安裝PostgreSQL。 如果尚未安裝,請轉到其下載頁面并進行安裝。
接下來需要做的是為項目創建一個Postgres用戶和數據庫。 為此,您可以使用Postgres CLI。 您應該能夠運行以下命令: psql -V并得到如下響應:
psql (PostgreSQL) 11.12為您的JPA實體創建PostgreSQL數據庫
在使用數據庫之前,您需要做一些事情。 你需要:
本教程使用jpatutorial作為用戶名,并使用springbootjpa作為數據庫名。 如果愿意,可以隨意更改這些值,但是您必須記住在整個教程中都使用自定義值。
從終端輸入psql進入Postgres shell。 然后輸入以下命令。
創建一個用戶
create user jpatutorial;外殼程序應響應: CREATE ROLE
不要忘記分號! 我永遠也不會這樣做。 我絕對不是憑經驗說話。 但是,如果你沒有在分號鍵入psql不處理的命令,你可以在沮喪迷茫失去20-30分鐘,不知道發生了什么事,直到你進入一個分號,在這一點上,試圖處理所有的命令。
給用戶密碼
alter user jpatutorial with encrypted password '<your really secure password>';外殼程序應使用以下命令響應: ALTER ROLE 。
創建數據庫
create database springbootjpa;外殼程序應使用以下命令響應: CREATE DATABASE 。
授予特權
grant all privileges on database springbootjpa to jpatutorial;外殼應以GRANT響應。
最后,如果需要,鍵入\q退出外殼。
如果您想了解更多有關psql ,可以看看Postgres的docs 。
構建一個Spring Boot資源服務器
從GitHub倉庫克隆啟動項目,并檢出start分支:
git clone -b start https://github.com/oktadeveloper/okta-spring-boot-jpa-example.git入門項目是一個全新的Spring Boot項目,僅具有一些Postgres特定的配置。 如果查看build.gradle文件,將看到PostgreSQL JPA連接器依賴性。 您還會注意到文件src/main/resources/hibernate.properties其唯一目的是擺脫對我們而言并不重要的煩人的警告/錯誤。 src/main/resources/application.yml文件還為您預先填充了一些屬性。
繼續并打開application.yml文件,并填寫您為數據庫用戶創建的密碼。 您還應該更新用戶名,數據庫名稱和端口(如果它們不同)。
spring: jpa: hibernate: ddl-auto: create database-platform: org.hibernate.dialect.PostgreSQLDialect datasource: url: "jdbc:postgresql://localhost:5432/springbootjpa" username: jpatutorial password: < your password >ddl-auto屬性指定了加載時休眠的行為。 選項包括:
- validate: 驗證架構,但不做任何更改
- 更新: 更新架構
- create: 創建模式,銷毀任何先前的數據
- create-drop: 類似于create,但是在會話關閉時也會刪除架構(用于測試)
您正在使用create 。 每次運行該程序時,都會從新表和數據開始創建一個新的數據庫。
database-platform實際上是不必要的。 Spring Data / Hibernate可以自動檢測平臺。 但是,如果沒有此屬性,那么如果您在未啟動Postgres服務器的情況下運行應用程序,則會得到一個非常無益的錯誤,即未添加此config屬性而不是被告知要啟動服務器。 發生這種情況是因為Hibernate無法自動檢測數據庫平臺,因此在抱怨實際上沒有正在運行的服務器之前先抱怨一下。
使用./gradlew bootRun運行應用程序。 您應該會看到以下內容:
2018-11-21 09:27:50.233 INFO 31888 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Located MBean 'dataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=dataSource,type=HikariDataSource] 2018-11-21 09:27:50.302 INFO 31888 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2018-11-21 09:27:50.308 INFO 31888 --- [ main] c.o.s.SpringBootJpaApplication : Started SpringBootJpaApplication in 21.361 seconds (JVM running for 21.848) <=========----> 75% EXECUTING [4m 26s] > :bootRun但是,它并沒有做太多事情。 沒有域模型,資源存儲庫或控制器類。
使用Spring Data和JPA添加域類
域或模型是您將存儲的數據的程序表示形式。 Spring Data和JPA的神奇之處在于,Spring可以采用Java類并將其轉換為數據庫表。 它甚至會自動生成必要的加載和保存方法。 最好的部分是(或多或少)這與數據庫無關。
您在本教程中使用的是PostgreSQL,并且可以通過更改build.gradle文件中的依賴項輕松地將其切換到MySQL。 當然,還要創建一個MySQL數據庫并更新application.yml文件中的必要屬性。 這對于測試,開發和長期維護非常有用。
繼續閱讀以學習如何開發一個簡單的服務器來存儲皮劃艇類型。
在com.okta.springbootjpa程序包中創建一個名為Kayak.java的Java文件。 您的皮劃艇模型將具有名稱,所有者,值和品牌/模型。
package com.okta.springbootjpa;import lombok.Data;import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id;@Entity // This tells Hibernate to make a table out of this class @Data // Lombok: adds getters and setters public class Kayak {public Kayak(String name, String owner, Number value, String makeModel) {this.name = name;this.owner = owner;this.value = value;this.makeModel = makeModel;}@Id@GeneratedValue(strategy=GenerationType.AUTO)private Integer id;private final String name;private String owner;private Number value;private String makeModel; }該項目使用Lombok來避免必須編寫大量的儀式獲取器,設置器和諸如此類的東西。 您可以查看他們的文檔 ,或更具體地說是您正在使用的@Data注釋 。
@Entity注釋告訴Spring此類是模型類,應轉換為數據庫表。
大多數屬性可以自動映射。 但是, id屬性用幾個注釋修飾,因為我們需要告訴JPA這是ID字段,并且應該自動生成它。
使用Spring Data JPA實現CRUD存儲庫
定義了域類后,Spring知道足以構建數據庫表,但是它沒有定義任何控制器方法。 沒有數據的輸出或輸入。 Spring使添加資源服務器變得微不足道。 實際上,它是如此瑣碎,您可能不會相信。
在包com.okta.springbootjpa ,創建一個名為KayakRepository.java的接口。
package com.okta.springbootjpa;import org.springframework.data.repository.CrudRepository; import org.springframework.data.rest.core.annotation.RepositoryRestResource;@RepositoryRestResource public interface KayakRepository extends CrudRepository<Kayak, Integer> { } 而已!
現在,您可以從資源服務器創建,讀取,更新和刪除皮劃艇。 在短短的幾秒鐘內,您將精確地完成此操作,但在此之前,請進行其他更改。
將以下init()方法添加到SpringBootJpaApplication類中:
應用程序啟動時將運行此方法。 它將一些樣本數據加載到資源服務器中,只是為了讓您在下一節中有所了解。
測試您的Spring Boot資源服務器
HTTPie是一個很棒的命令行實用工具,它使對資源服務器的請求運行變得容易。 如果未安裝HTTPie,請使用brew install httpie進行brew install httpie 。 或前往他們的網站并實現它。 或者只是跟隨。
確保您的Spring Boot應用正在運行。 如果不是,請使用./gradlew bootRun啟動它。
針對您的資源服務器運行GET請求: http :8080/kayaks ,這是http GET http://localhost:8080/kayaks簡寫。
您會看到以下內容:
HTTP/1.1 200 Content-Type: application/hal+json;charset=UTF-8 Date: Wed, 21 Nov 2018 20:39:11 GMT Transfer-Encoding: chunked{"_embedded": {"kayaks": [{"_links": {"kayak": {"href": "http://localhost:8080/kayaks/1"},"self": {"href": "http://localhost:8080/kayaks/1"}},"makeModel": "NDK","name": "sea","owner": "Andrew","value": 300.12},{"_links": {"kayak": {"href": "http://localhost:8080/kayaks/2"},"self": {"href": "http://localhost:8080/kayaks/2"}},"makeModel": "Piranha","name": "creek","owner": "Andrew","value": 100.75},{"_links": {"kayak": {"href": "http://localhost:8080/kayaks/3"},"self": {"href": "http://localhost:8080/kayaks/3"}},"makeModel": "Necky","name": "loaner","owner": "Andrew","value": 75}]},"_links": {"profile": {"href": "http://localhost:8080/profile/kayaks"},"self": {"href": "http://localhost:8080/kayaks"}} }此輸出使您對Spring Boot資源返回的數據格式有了一個非常扎實的想法。 您也可以使用POST添加新的皮劃艇。
命令:
http POST :8080/kayaks name="sea2" owner="Andrew" value="500" makeModel="P&H"回復:
HTTP/1.1 201 Content-Type: application/json;charset=UTF-8 Date: Wed, 21 Nov 2018 20:42:14 GMT Location: http://localhost:8080/kayaks/4 Transfer-Encoding: chunked{"_links": {"kayak": {"href": "http://localhost:8080/kayaks/4"},"self": {"href": "http://localhost:8080/kayaks/4"}},"makeModel": "P&H","name": "sea2","owner": "Andrew","value": 500 }如果您再次列出皮劃艇( http :8080/kayaks ),則會在列出的項目中看到新的皮劃艇。
HTTP/1.1 200 Content-Type: application/hal+json;charset=UTF-8 Date: Wed, 21 Nov 2018 20:44:22 GMT Transfer-Encoding: chunked{"_embedded": {"kayaks": [...{"_links": {"kayak": {"href": "http://localhost:8080/kayaks/4"},"self": {"href": "http://localhost:8080/kayaks/4"}},"makeModel": "P&H","name": "sea2","owner": "Andrew","value": 500}]},... }您也可以刪除皮劃艇。 運行以下命令: http DELETE :8080/kayaks/4這將刪除ID = 4的皮劃艇或我們剛剛創建的皮劃艇。 第三次獲取皮艇列表,您會發現它已經消失了。
使用Spring Boot,只需很少的代碼,就可以創建功能全面的資源服務器。 此數據將持久保存到您的Postgres數據庫中。
您可以使用Postgres命令外殼來驗證這一點。 在終端上,鍵入psql進入shell,然后鍵入以下命令。
連接到數據庫:
\connect springbootjpapsql (9.6.2, server 9.6.6) You are now connected to database "springbootjpa" as user "cantgetnosleep".顯示表內容:
SELECT * FROM kayak;id | make_model | name | owner | value ----+------------+--------+--------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------1 | NDK | sea | Andrew | \xaced0005737200106a6176612e6c616e67...8704072c1eb851eb8522 | Piranha | creek | Andrew | \xaced0005737200106a6176612e6c616e672e...0787040593000000000003 | Necky | loaner | Andrew | \xaced00057372000e6a6176612e6c616e67...7870000000000000004b5 | P&H | sea2 | Andrew | \xaced0005737200116a6176612e6...08b0200007870000001f4 (4 rows)需要注意的幾件事。 首先,請注意, 值被存儲為二進制對象,因為它被定義為Number類型而不是原始類型(double,float或int)。 其次,請記住,由于ddl-auto: create application.yml文件中的ddl-auto: create行,在application.yml每次啟動時都將擦除此數據并重新創建整個表。
設置身份驗證
Okta是軟件即服務身份,身份驗證和授權提供者。 雖然我確實從事過將所有項目外包給SaaS提供商的項目,但所產生的問題超出了其承諾解決的問題,但身份驗證和授權是使這種模型完全有意義的地方。 在線安全很難。 發現漏洞,必須快速更新服務器。 標準變更和代碼需要修改。 所有這些更改都有可能創建新的漏洞。 讓Okta處理安全性意味著您可以擔心使您的應用程序與眾不同的事情。
為了向您展示設置的簡便性,您將集成Okta OAuth并將基于令牌的身份驗證添加到資源服務器。 如果尚未注冊,請訪問developer.okta.com并注冊一個免費帳戶。 擁有帳戶后,通過單擊“ 應用程序”頂部菜單項,然后單擊“ 添加應用程序”按鈕,打開開發人員儀表板并創建OpenID Connect(OIDC)應用程序 。
選擇單頁應用程序 。
默認應用程序設置很好,除了您需要添加登錄重定向URI : a 。 您將在稍后使用它來檢索測試令牌。
另外,請注意您的客戶ID ,稍后您將需要它。
配置您的Spring Boot資源服務器以進行令牌認證
Okta使添加令牌身份驗證到Spring Boot非常容易。 他們有一個名為Okta Spring Boot Starter的項目( 請查看GitHub項目 ),將整個過程簡化為幾個簡單的步驟。
在您的build.gradle文件中添加幾個依賴build.gradle 。
compile('org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.1.0.RELEASE') compile('com.okta.spring:okta-spring-boot-starter:0.6.1')將以下內容添加到build.gradle文件的底部(這解決了logback日志記錄依賴性沖突)。
configurations.all { exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging' exclude group: 'org.springframework.boot', module: 'logback-classic' }接下來,你需要一些配置添加到您的application.yml文件,替換{yourClientId}從你1563 OIDC應用程序和客戶端ID {yourOktaDomain}與1563網址。 像https://dev-123456.oktapreview.com東西。
okta: oauth2: issuer: https://{yourOktaDomain}/oauth2/default client-id: {yourClientId} scopes: openid profile email最后,您需要將@EnableResourceServer批注添加到SpringBootVueApplication類。
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;@EnableResourceServer // <- add me @SpringBootApplication public class SpringBootJpaApplication { public static void main(String[] args) { SpringApplication.run(SpringBootJpaApplication.class, args); }... }測試受保護的Spring Boot服務器
停止您的Spring Boot服務器并使用以下./gradlew bootRun重新啟動它: ./gradlew bootRun
從命令行運行一個簡單的GET請求。
http :8080/kayaks您會得到未經授權的401 /。
HTTP/1.1 401 Cache-Control: no-store Content-Type: application/json;charset=UTF-8{"error": "unauthorized","error_description": "Full authentication is required to access this resource" }生成訪問令牌
要立即訪問服務器,您需要一個有效的訪問令牌。 您可以使用OpenID Connect調試器來幫助您完成此任務。 在另一個窗口中,打開oidcdebugger.com 。
授權URI : https://{yourOktaUrl}/oauth2/default/v1/authorize ,其中{yourOktaUrl}替換為您的實際Okta預覽URL。
重定向URI :不變。 這是您在上面的OIDC應用程序中添加的值。
客戶ID :來自您剛創建的OIDC應用程序。
范圍 : openid profile email 。
狀態 :您要通過OAuth重定向過程傳遞的任何值。 我將其設置為{} 。
Nonce :可以一個人呆著。 Nonce表示“編號已使用一次”,是一種簡單的安全措施,用于防止同一請求被多次使用。
響應類型 : token 。
響應方式 : form_post 。
點擊發送請求 。 如果您尚未登錄developer.okta.com,則需要登錄。如果(可能的話)已經登錄,則將為您的登錄身份生成令牌。
使用訪問令牌
您可以通過在Bearer類型的Authorization請求標頭中包含令牌來使用令牌。
Authorization: Bearer eyJraWQiOiJldjFpay1DS3UzYjJXS3QzSVl1MlJZc3VJSzBBYUl3NkU4SDJfNVJr...通過HTTPie發出請求:
http :8080/kayaks 'Authorization: Bearer eyJraWQiOiJldjFpay1DS3UzYjJXS3QzSVl1...'添加基于組的授權
到目前為止,授權方案還算是二進制的。 該請求是否帶有有效令牌。 現在,您將添加基于組的身份驗證。 請注意,盡管有時在臭名昭著的網站上可以互換使用,但角色和組卻不是一回事,它們是實現授權的不同方法。
角色是用戶可以繼承的權限集合的集合。 組是一組標準權限分配給的用戶的集合。 但是,在令牌的范圍以及如何將Spring Security與JPA結合使用時,實現是完全相同的。 它們都以字符串“ authority”的形式從OAuth OIDC應用程序傳遞給Spring,因此目前它們基本上可以互換。 不同之處在于受保護的內容及其定義方式。
要在Okta中使用基于組的授權,您需要在訪問令牌中添加一個“組”聲明。 創建一個Admin組(“ 用戶” >“ 組” >“ 添加組” )并將您的用戶添加到其中。 您可以使用注冊時使用的帳戶,也可以創建一個新用戶(“ 用戶” >“ 添加人” )。 導航到“ API” >“ 授權服務器” ,單擊“ 授權服務器”選項卡,然后編輯默認選項卡。 點擊索賠標簽,然后添加索賠 。 將其命名為“組”,并將其包含在訪問令牌中。 將值類型設置為“ Groups”,并將過濾器設置為.*的正則表達式。
使用OIDC調試器創建一個新的訪問令牌。 通過轉到jsonwebtoken.io并輸入生成的訪問令牌,來查看已解碼的令牌。
有效載荷看起來像這樣:
{"ver": 1,"jti": "AT.Hk8lHezJNw4wxey1czypDiNXJUxIlKmdT16MrnLGp9E","iss": "https://dev-533919.oktapreview.com/oauth2/default","aud": "api://default","iat": 1542862245,"exp": 1542866683,"cid": "0oahpnkb44pcaOIBG0h7","uid": "00ue9mlzk7eW24e8Y0h7","scp": ["email","profile","openid"],"sub": "andrew.hughes@mail.com","groups": ["Everyone","Admin"] }組聲明包含用戶分配到的組。 您用來登錄developer.okta.com網站的用戶也將是“所有人”組和“管理員”組的成員。
為了使Spring Boot和資源服務器在基于組的授權下都能正常運行,您需要對代碼進行一些更改。
首先,在com.okta.springbootjpa包中添加一個名為SecurityConfiguration的新Java類。
package com.okta.springbootjpa;import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;@EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfiguration extends WebSecurityConfigurerAdapter { }需要此配置類來啟用@PreAuthorize批注,該批注將用于基于組成員身份保護資源服務器。
接下來,將@PreAuthorize批注添加到KayakRepository ,如下所示:
... import org.springframework.security.access.prepost.PreAuthorize; ...@RepositoryRestResource @PreAuthorize("hasAuthority('Admin')") public interface KayakRepository extends CrudRepository<Kayak, Long> { }最后,在SpringBootJpaApplication , 刪除 ApplicationRunner init(KayakRepository repository)方法(或僅注釋掉@Bean批注)。 如果跳過此步驟,構建將失敗,并顯示以下錯誤:
AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext@PreAuthorize批注實際上阻止init()方法以編程方式創建自舉數據,因為沒有用戶登錄。因此,該方法運行時會引發錯誤。
請注意,您在@PreAuthorize批注中使用hasAuthority() ,而不是 hasRole() 。 區別在于hasRole()期望組或角色在ALL CAPS中并且具有ROLE_前綴。 這可以被配置,當然,但hasAuthority()來沒有這個包袱,簡單地檢查任何權利要求你定義為okta.oauth2.roles-claim在application.yml 。
在您的Spring Boot應用程序中測試管理員用戶
重新啟動您的Spring Boot應用程序(以./gradlew bootRun )。
嘗試未經身份驗證的GET請求:v class =“ highlighter-rouge”> http:8080 / kayaks。
HTTP/1.1 401 Cache-Control: no-store Content-Type: application/json;charset=UTF-8{"error": "unauthorized","error_description": "Full authentication is required to access this resource" }使用令牌嘗試一下。
命令:
http :8080/kayaks 'Authorization: Bearer eyJraWQiOiJldjFpay1DS3UzYjJXS3QzSVl1MlJZc3VJSzBBYUl3NkU4SDJf...'回復:
HTTP/1.1 200 Cache-Control: no-cache, no-store, max-age=0, must-revalidate Content-Type: application/hal+json;charset=UTF-8{"_embedded": {"kayaks": []},"_links": {"profile": {"href": "http://localhost:8080/profile/kayaks"},"self": {"href": "http://localhost:8080/kayaks"}} }有效! 我們沒有任何皮劃艇,因為我們必須刪除上面的init()方法,因此_embedded.kayaks數組為空。
提示:今后,如果您不想復制并粘貼整個巨大的令牌字符串,則可以將其存儲到shell變量中,然后像這樣重用它:
TOKEN=eyJraWQiOiJldjFpay1DS3UzYjJXS3QzSVl1MlJZc3VJSzBBYUl3NkU4SDJf... http :8080/kayaks 'Authorization: Bearer $TOKEN'創建一個非管理員用戶
為了演示基于組的授權,您需要在Okta上創建一個不是管理員的新用戶。 轉到developer.okta.com儀表板。
從頂部菜單中,選擇“ 用戶和人員” 。
單擊添加人按鈕。
給用戶一個名字 , 姓氏和用戶名 (也將是主要電子郵件 )。 值無關緊要,并且您將不必檢查電子郵件。 您只需要知道電子郵件地址/用戶名和密碼,即可在一分鐘內登錄Okta。
密碼 :將下拉菜單更改為“ 由管理員設置” 。
為用戶分配密碼。
點擊保存 。
您剛剛創建的用戶不是Admin組的成員,而是默認組Everyone的成員。
在Spring Boot應用程序中基于測試組的授權
注銷您的Okta開發人員儀表板。
返回OIDC調試器并生成一個新令牌。
這次,以新的非管理員用戶身份登錄。 系統會要求您選擇一個安全問題,然后將您重定向到https://oidcdebugger.com/debug頁面,您可以在其中復制令牌。
如果愿意,可以轉到jsonwebtoken.io并解碼新令牌。 在有效內容中, 子聲明將顯示用戶的電子郵件/用戶名,而組聲明將僅顯示“ 所有人”組。
{..."sub": "test@gmail.com","groups": ["Everyone"] }如果使用新令牌在/kayaks端點上發出請求,則會收到403 / Access Denied。
http :8080/kayaks 'Authorization: Bearer eyJraWQiOiJldjFpay1DS3UzYjJX...'HTTP/1.1 403 ...{"error": "access_denied","error_description": "Access is denied" }為了演示@PreAuthorize批注的真正功能,請創建一個方法級別的安全約束。 將KayakRepository類更改為以下內容:
@RepositoryRestResource public interface KayakRepository extends CrudRepository<Kayak, Long> { @PreAuthorize("hasAuthority('Admin')") <S extends Kayak> S save(S entity); }這僅將save()方法限制為Admin組的成員。 僅需身份驗證即可限制存儲庫的其余部分,而無需特定的組成員身份。
重新啟動Spring Boot服務器。 再次運行相同的請求。
http :8080/kayaks 'Authorization: Bearer eyJraWQiOiJldjFpay1DS3UzYjJX...'HTTP/1.1 200 ...{"_embedded": {"kayaks": []},"_links": {"profile": {"href": "http://localhost:8080/profile/kayaks"},"self": {"href": "http://localhost:8080/kayaks"}} }_.embedded.kayaks存儲庫為空,因此_.embedded.kayaks是一個空數組。
嘗試創建一個新的皮劃艇。
http POST :8080/kayaks name="sea2" owner="Andrew" value="500" makeModel="P&H" "Authorization: Bearer eyJraWQiOiJldjFpay1DS3UzYjJX..."您將獲得另一個403。“保存”在此處等于HTML POST。
但是,如果您使用從原始管理員帳戶生成的令牌,則可以使用。
注意:您的令牌可能已過期,您必須再次注銷developer.okta.com,然后在OIDC調試器上重新生成令牌。
使用您的管理員帳戶生成的令牌發布新的皮劃艇。
這次您將獲得201。
HTTP/1.1 201 Cache-Control: no-cache, no-store, max-age=0, must-revalidate Content-Type: application/json;charset=UTF-8 ...{"_links": {"kayak": {"href": "http://localhost:8080/kayaks/1"},"self": {"href": "http://localhost:8080/kayaks/1"}},"makeModel": "P&H","name": "sea2","owner": "Andrew","value": 500 }成功!
看一下Spring Data的CrudRepository接口,以了解可以被覆蓋的方法以及分配給方法級安全性的方法。 @PreAuthorize注釋不僅可以用于組,還可以使用更多的內容。 可以利用Spring的表達語言(SpEL)的全部功能。
public interface CrudRepository<T, ID> extends Repository<T, ID> {<S extends T> S save(S entity);<S extends T> Iterable<S> saveAll(Iterable<S> entities);Optional<T> findById(ID id);boolean existsById(ID id);Iterable<T> findAll();Iterable<T> findAllById(Iterable<ID> ids);long count();void deleteById(ID id);void delete(T entity);void deleteAll(Iterable<? extends T> entities);void deleteAll(); }就是這樣! 很酷吧? 在本教程中,您將建立一個PostgreSQL數據庫,創建一個Spring Boot資源服務器,該服務器使用Spring Data和JPA來持久化數據模型,然后將該數據模型轉換為REST API,只需很少的代碼。 此外,您還使用Okta向服務器應用程序添加了OIDC身份驗證和OAuth 2.0授權。 最后,您實現了一個簡單的基于組的授權方案。
如果您想查看這個完整的項目,可以在GitHub上的倉庫中找到@ oktadeveloper / okta-spring-boot-jpa-example 。
請留意本系列中的下一篇文章,該文章將介紹在Spring WebFlux中使用NoSQL數據庫(MongoDB)。
了解有關Spring Boot,Spring Security和安全身份驗證的更多信息
如果您想了解有關Spring Boot,Spring Security或現代應用程序安全性的更多信息,請查看以下任何出色的教程:
- Spring Boot,OAuth 2.0和Okta入門
- 15分鐘內將單一登錄添加到您的Spring Boot Web App
- 使用多重身份驗證保護您的Spring Boot應用程序安全
- 使用Spring Boot和GraphQL構建安全的API
如果您想深入研究,請查看Okta Spring Boot Starter GitHub項目 。
這對于Spring Data和保護Spring Boot項目是一個很好的參考: https : //docs.spring.io/spring-data/rest/docs/current/reference/html/
當將PostgreSQL與JPA和Hibernate一起使用時, Vlad Mihalcea有一個很棒的教程,標題為《 9個高性能技巧》 。
Baeldung有一個關于保護Spring Data / Spring Boot項目中的方法的有用教程: https ://www.baeldung.com/spring-security-method-security
最后,如果您需要在Mac OS X上使用PostgreSQL的更多幫助,請參閱此codementor.io教程 。
如果您對此帖子有任何疑問,請在下面添加評論。 有關更多精彩內容, 請在Twitter上關注@oktadev , 在Facebook上關注我們,或訂閱我們的YouTube頻道 。
``使用PostgreSQL使用Spring Boot和JPA構建應用程序''最初于2018年12月13日發布在Okta開發者博客上。
“我喜歡編寫身份驗證和授權代碼。” ?從來沒有Java開發人員。 厭倦了一次又一次地建立相同的登錄屏幕? 嘗試使用Okta API進行托管身份驗證,授權和多因素身份驗證。
翻譯自: https://www.javacodegeeks.com/2018/12/build-basic-spring-boot-using-postgresql.html
總結
以上是生活随笔為你收集整理的使用PostgreSQL使用Spring Boot和JPA构建基本应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网件ddns(网件ddos)
- 下一篇: 交管12123备案驾驶证是什么意思(备案