使用Okta的单点登录保护您的Vert.x服务器
“我喜歡編寫身份驗證和授權代碼?!??從來沒有Java開發人員。 厭倦了一次又一次地建立相同的登錄屏幕? 嘗試使用Okta API進行托管身份驗證,授權和多因素身份驗證。
Vert.x是Spring生態系統中增長最快的元素之一,保護Vert.x服務器可能是一個挑戰。 部署Okta可以讓您向服務器添加安全的單點登錄,同時還可以授予您訪問有關用戶的大量信息的權限。 本教程將指導您站起一個新的Vert.x服務器,并將其與Okta集成以進行安全的用戶管理。
三步OAuth流程快速回顧
此示例將使用稱為三足流(單點登錄的實質)的第三方提供程序OAuth流。 在開始編寫代碼之前,簡要回顧一下此過程可能會有所幫助。
問題
我是Web服務器,我想保護我的網站并要求用戶登錄。但是,編寫,維護和管理用戶身份是很多工作。
解決方案
讓別人來處理它。 為此,我(Web服務器),我的用戶(可能在Web瀏覽器上)以及為我處理auth的人(在此示例中為Okta)之間需要一些合作。 這三個合作的參與者是三腿OAuth流的三個“腿”。 他們經歷的過程是三向握手:
完成此示例后,上述握手將在幕后發生。 Vert.x提供了一個方便的OAuth庫來為您完成整個過程-您所需要做的就是對其進行配置并進行適當的注冊。 這就是本教程演示的內容。
作為入門指南,本文假定僅基本熟悉Java和一些Java要素,例如Maven。 如果您已經在運行Vert.x服務器,請隨時快速了解相關內容:您將在“ 配置Vert.x OAuth處理程序”部分中與Okta集成。
完整的代碼示例(包括imports和pom.xml)可以在Github上找到。
啟動新的Vert.x服務器
要開始工作,請訪問Vert.x Starter頁面并生成一個新項目。 對于本教程,您可以保留所有默認值,并包括Vert.x Web , OAuth和Vert.x Config依賴項:
單擊本地生成,下載和解壓縮后,您應該看到以下簡單目錄結構:
在demo目錄中使用mvn compile exec:java運行時,應在端口8080上啟動服務器:
在瀏覽器中訪問http://localhost:8080將返回令人放心的hello world響應:
在這一點上,下一步是在繼續添加身份驗證之前切換到https。 但是,為了使本教程簡短而集中,將跳過該部分,并且示例將繼續使用未加密的http服務器模式。
引入Vert.x配置
Vert.x提供了一個通用的配置庫,盡管要比Spring設置更多的工作。 本示例將使用一些配置值,因此您可以借此機會將Vert.x Config添加到項目中。 如果在創建啟動程序項目時指定了Vert.x Config,則該依賴項應該已經存在于pom.xml 。
<dependency><groupId>io.vertx</groupId><artifactId>vertx-config</artifactId><version>${vertx.version}</version> </dependency>創建一個名為src/main/application.json的文件,并添加以下內容:
{"clientId": "{okta-client-id}","clientSecret": "{okta-client-secret}","issuer": "https://{yourOktaDomain}/oauth2/default","callbackUrl": "http://localhost:8080/login","port": 8080 }您將很快更新這些值。 現在,在src/main/java/com/example/demo/MainVerticle.java ,將start()方法的內容替換為以下內容,這將加載配置。 請注意,完成后,它將調用一個尚不存在的名為startServer()的方法。 您將在下一節中添加它。
@Override public void start() throws Exception {ConfigStoreOptions fileStore = new ConfigStoreOptions().setType("file").setConfig(new JsonObject().put("path", "src/main/application.json"));ConfigRetrieverOptions options = new ConfigRetrieverOptions().addStore(fileStore);ConfigRetriever retriever = ConfigRetriever.create(vertx, options);retriever.getConfig(ar -> {if (ar.failed()) {System.err.println("failed to retrieve config.");} else {config().mergeIn(ar.result());startServer();}}); }整合Vert.x路由器
通過使用Vert.x路由器 ,您將能夠輕松攔截對敏感端點的呼叫并強制進行預身份驗證。 為此,您現在將在src/main/java/com/example/demo/MainVerticle.java實現startServer()方法:
void startServer() {Router router = Router.router(vertx);router.route("/private/secret").handler(ctx -> {ctx.response().end("Hi");});vertx.createHttpServer().requestHandler(router::accept).listen(config().getInteger("port")); }在上面的示例中,您已經在/private/secret創建了一個新端點,目的是盡快保護/private路徑下的每個端點。 但首先,需要設置Vert.x OAuth處理程序。
創建Okta帳戶并收集憑據
如果您還沒有免費的Okta帳戶,則可以按照以下說明創建一個帳戶并設置您的第一個Okta應用程序。 您需要收集四個關鍵信息:
- 客戶編號-例如: oot9wrjjararhfaa
- 客戶機密-(保持機密!)
- 發行者–例如: https : //dev-123123.oktapreview.com/oauth2/default…請確保包括/ oauth2 / default路徑!
- 回調網址-如果遵循上述說明,則為http:// localhost:8080 / login 。
現在可以在src/main/application.json文件中使用這些值。
配置Vert.x OAuth處理程序
Vert.x帶有一個現成的OAuth管理器,可以與Okta作為身份提供者很好地集成在一起。 為了使內容整潔,您將在src/main/java/com/example/demo/MainVerticle.java中創建一個單獨的工廠方法,該方法會生成已配置的OAuth處理程序。 將以下內容添加到MainVerticle類中,將下面的客戶端信息替換為從Okta開發人員儀表板獲得的帳戶詳細信息:
AuthHandler getOAuthHandler(Router router) {OAuth2Auth oauth2 = OAuth2Auth.create(vertx, OAuth2FlowType.AUTH_CODE, new OAuth2ClientOptions().setClientID(config().getString("clientId")).setClientSecret(config().getString("clientSecret")).setSite(config().getString("issuer")).setTokenPath("/v1/token").setAuthorizationPath("/v1/authorize").setUserInfoPath("/v1/userinfo").setUseBasicAuthorizationHeader(false));OAuth2AuthHandler authHandler = OAuth2AuthHandler.create(oauth2, config().getString("callbackUrl"));authHandler.extraParams(new JsonObject("{\"scope\":\"openid profile email\"}"));authHandler.setupCallback(router.route());return authHandler; }在上面的示例中,請注意三個請求的范圍: openid , profile和email 。 將來的帖子將探討其他范圍和授權級別,但是目前,這三個將提供絕對必要的條件(例如用戶名和電子郵件地址)。 使用電子郵件地址,您還可以直接查詢Okta的API以獲取有關用戶的其他信息,并執行帳戶管理任務。
攔截并授權受保護的端點
現在已經準備好AuthHandler ,它需要在對任何受保護端點的請求處理之前并驗證用戶身份。 通過使用通配符將其注冊為/private/下所有路徑的頂級處理程序,只需為您將來可能創建的所有處理程序處理一次即可。 然后可以保證/private/路徑下的任何請求處理程序都將確保,在調用該請求處理程序時,它將僅來自經過正確身份驗證的用戶。
如下所示更改MainVerticle類的startServer()方法,以生成并注冊處理程序:
public void startServer() {Router router = Router.router(vertx);//create and register the auth handler to intercept all//requests below the /private/ URI:AuthHandler authHandler = getOAuthHandler(router);router.route("/private/*").handler(authHandler);router.route("/private/secret").handler(ctx -> {ctx.response().end("Hi");});vertx.createHttpServer().requestHandler(router::accept).listen(config().getString(“port”)); }這將是重新啟動服務器并確保一切正常運行的絕佳時機。 通過再次運行mvn compile java:exec并從瀏覽器中訪問http://localhost:8080/private/secret ,您現在應該被自動重定向到Okta的登錄頁面。 登錄后,應將您重定向回您的站點,以繼續響應原始的/private/secret請求。
從JWT提取用戶信息
現在,您的/private/ API的調用者已登錄,接下來您需要的是他們的信息。 它以JSON Web令牌的形式提供,必須將其提取并解碼。 Vert.x OAuth處理程序將其隱藏為名為Principal的字符串化JSON對象的命名成員,該對象本身是上下文用戶對象的組成部分。 然后使用您選擇的JWT庫對該編碼的令牌進行解碼和驗證。 本示例使用Okta的JWT驗證程序庫 。
access_token和id_token均可用,但是本教程將僅解碼id_token 。 如果需要,還有一個類似的函數可以對access_token進行解碼。 為此,請在pom.xml包含Okta JWT lib依賴項:
<dependency><groupId>com.okta.jwt</groupId><artifactId>okta-jwt-verifier</artifactId><version>0.2.0</version> </dependency>…并將以下新函數添加到MainVertical類中:
Map<String, Object> getIdClaims(RoutingContext ctx) {try {JwtVerifier jwtVerifier = new JwtHelper().setIssuerUrl(config().getString(“issuer”)).setAudience("api://default").setClientId(config().getString("clientId")).build();Jwt idTokenJwt = jwtVerifier.decodeIdToken(ctx.user().principal().getString("id_token"), null);return idTokenJwt.getClaims();} catch (Exception e) {//do something with the exception...return new HashMap<>();} }就是這樣! 現在,您可以在請求處理程序中訪問用戶信息。 為了演示,可以對/private/secret處理程序進行更新以從JWT檢索聲明,如下所示:
void startServer() {Router router = Router.router(vertx);AuthHandler authHandler = getOAuthHandler(router);router.route("/private/*").handler(authHandler);router.route("/private/secret").handler(ctx -> {Map claims = getIdClaims(ctx);ctx.response().end("Hi " +claims.get("name") +", the email address we have on file for you is: "+claims.get("email"));});vertx.createHttpServer().requestHandler(router::accept).listen(config().getString(“port”)); }經過最后的更改,重新啟動服務器并再次點擊http://localhost:8080/private/secret ,您的瀏覽器現在應該顯示一條消息,其中包含您已通過身份驗證的用戶信息!
步步高升
恭喜,您現在擁有一臺高性能的Vert.x服務器,受到Okta先進的安全性和身份管理保護! Okta提供了Java SDK,用于進一步與用戶和帳戶進行交互,包括向用戶添加自定義數據和屬性。
感謝您的閱讀,并且一如既往,請在下面的評論中向我們提問。 我們希望您在Twitter @OktaDev上關注我們,或者從我們的博客中Java內容:
- Spring Security 5.0和OIDC入門
- 使用Spring Boot和React進行Bootiful開發
- 使用Kong Gateway集中身份驗證
- 使用Angular 5.0和Spring Boot 2.0構建基本的CRUD應用
- 使用Spring Boot和OAuth保護您的SPA
“我喜歡編寫身份驗證和授權代碼?!??從來沒有Java開發人員。 厭倦了一次又一次地建立相同的登錄屏幕? 嘗試使用Okta API進行托管身份驗證,授權和多因素身份驗證。
使用Okta將Single Sign-on添加到您的Vert.x Server最初于2018年1月11日發布在Okta開發人員博客上。
翻譯自: https://www.javacodegeeks.com/2018/03/secure-vert-x-server-single-sign-okta.html
總結
以上是生活随笔為你收集整理的使用Okta的单点登录保护您的Vert.x服务器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 袁隗怎么读 袁隗的简介
- 下一篇: Apache Kafka简介