javascript
使用Spring Security进行简单身份验证
朋友不允許朋友寫用戶身份驗證。 厭倦了管理自己的用戶? 立即嘗試Okta的API和Java SDK。 在幾分鐘之內即可對任何應用程序中的用戶進行身份驗證,管理和保護。
身份驗證對于除了最基本的Web應用程序之外的所有應用程序都至關重要。 誰在發出請求,需要數據或想要更新或刪除數據? 您可以確定請求來自指定的用戶或代理嗎? 在當今的計算機安全環境中,很難確定地回答這個問題。 幸運的是,絕對沒有理由重新發明輪子。
Spring Boot和Spring Security是Web應用程序開發的強大組合。 使用相對較少的代碼行,您可以實現各種身份驗證系統。 這些系統由專家根據規范進行測試,更新和實施。
在本教程中,您將構建一個非常簡單的Spring Boot應用程序,該應用程序從basic-auth開始,并逐步進行基于表單的身份驗證,基于表單的自定義身份驗證以及使用Okta作為OAuth提供者的OAuth 2.0 / OpenID Connect。 我們還將介紹SAML身份驗證。 但是,Spring Security SAML實現目前正在過渡中,尚未更新為最新版本的Spring Boot。
本教程專門研究身份驗證,將授權保留另一天。 身份驗證可以回答問題:誰在發出請求。 授權是在身份驗證之后進行的,并回答以下問題:是否允許經過身份驗證的用戶發出特定請求?
使用Spring Security進行身份驗證的要求和假設
本教程假定您對Java和Spring Boot基本熟悉。 該項目利用了Gradle構建系統(因為我發現Groovy DSL永遠比XML更可取)。 但是,您不需要安裝Gradle,因為所有項目都包括Gradle包裝器。
您不需要全面了解OAuth 2.0和OpenID Connect(OIDC)–令人欣慰的是,由于OAuth 2.0和OpenID Connect有時非常復雜,詳細且繁瑣。 我仍在努力了解它的許多方面。 但是,基本的了解會有所幫助。 如果您想更進一步,本文結尾處的一些鏈接可以為您提供幫助。
非常(非常)簡短地講,OAuth 2.0是開放授權(開放授權)的第二個主要版本。 來自OAuth規范委員會的信息 :“ OAuth 2.0致力于簡化客戶端開發人員的工作,同時為Web應用程序,桌面應用程序,移動電話和客廳設備提供特定的授權流程。” 注意兩件事:1)僅是授權,因此沒有身份驗證; 2)這是一個規范,因此沒有實現。 OIDC建立在OAuth 2.0之上,以使用定義良好的令牌添加身份層(身份驗證)。
Okta的Spring Security身份驗證
Okta是一家身份訪問和管理公司,提供大量的軟件即服務身份產品。 我們具有OAuth 2.0和OpenID Connect的實現,該實現使向Spring Boot應用程序添加單點登錄(SSO)變得容易。
我們的API使您能夠:
- 驗證和授權用戶
- 存儲有關您的用戶的數據
- 執行基于密碼的社交登錄
- 通過多因素身份驗證保護您的應用程序
- 以及更多! 查看我們的產品文檔以獲取更多信息
注冊一個永久免費的開發者帳戶 ,完成后,再回來學習更多關于使用Spring Boot和Spring Security構建身份驗證的信息。
除此之外,您還需要一臺計算機和一個Web瀏覽器。 如果沒有這些,那么,你會在這里怎么樣?
下載Spring Security示例應用程序
繼續并從本教程的GitHub存儲庫下載示例應用程序。
git clone https://github.com/oktadeveloper/okta-spring-security-authentication-example.git在項目中,您將看到三個目錄:
- basic-auth
- form-auth
- okta-oauth
通過Spring Security深入了解基本身份驗證
到目前為止,基本身份驗證是最簡單的方法。 不幸的是,它是為在互聯網上更簡單的時間而設計的。 對于專業應用程序,它并不是真正起作用。 有時,當我需要一些簡單而又快速的工具來使臨時沖浪者脫離頁面時,我便將其用于內部工具。 但是,基本身份驗證在HTTP身份驗證標頭中以基本純文本格式(base64編碼)向用戶發送憑據。 因此,基本身份驗證應始終與SSL結合使用以保護用戶憑據。 基本身份驗證還使用瀏覽器生成的彈出面板來檢索用戶憑據。 面板不能設置樣式或自定義。
首先,看一下build.gradle文件。
plugins { id 'org.springframework.boot' version '2.1.5.RELEASE' id 'java' } apply plugin: 'io.spring.dependency-management' group = 'com.okta.springsecurityauth' version = '0.0.1-SNAPSHOT' sourceCompatibility = '1.8' repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' }此行設置Spring Boot版本:
id 'org.springframework.boot' version '2.1.5.RELEASE'這是包括Spring Security和Spring MVC的兩個依賴項。
implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-web'其余的幾乎都是樣板。
這是主應用程序文件( src/main/java/com/okta/springsecurityauth/Application.java )。
package com.okta.springsecurityauth; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }這是Java應用程序的入口點。 要注意的主要事情是數量很少。 @SpringBootApplication注釋告訴Spring引導所有Spring Boot優點。
接下來看一下WebController, src/main/java/com/okta/springsecurityauth/WebController.java 。
package com.okta.springsecurityauth; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class WebController { @RequestMapping("/")@ResponseBodypublic String index() {return "Welcome home!";} }Web控制器文件還有更多操作。 這是定義項目的唯一HTTP端點的地方。 該文件定義了一個簡單的home控制器,該控制器返回文本字符串。
@Controller批注告訴Spring該文件正在定義Web控制器端點。 @RequestMapping批注定義HTTP請求和控制器方法之間的映射。 @ResponseBody注釋告訴Spring該方法將直接以String的形式返回請求主體,而不是返回模板文件的名稱。
最后一個文件是定義所有安全性的位置。 巧妙地將其命名為SecurityConfiguration.java 。
看看src/main/java/com/okta/springsecurityauth/SecurityConfiguration.java
package com.okta.springsecurityauth; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .httpBasic(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user") .password("{noop}pass") // Spring Security 5 requires specifying the password storage format .roles("USER"); } }您會看到需要很少的配置。 在第一種方法中,將fluent API與HttpSecurity對象一起使用以配置Spring Security:激活安全性,對所有請求進行身份驗證,并使用HTTP basic。
第二種方法實際上只是本教程的一點技巧。 它配置內存中的身份驗證管理器,并創建一個憑據為user:pass 。
試一試吧! 在終端上,轉到項目的根目錄。
使用以下項目運行項目: ./gradlew bootRun 。
導航到http://localhost:8080 。
您將看到瀏覽器生成的登錄表單。 輸入憑證user并pass 。 您會看到一個成功的頁面,上面寫著“歡迎回家!”
使用Spring Security升級到基于表單的身份驗證
HTTP Basic身份驗證非常簡單,實際上在現實世界中并沒有那么有用。 基于表單的身份驗證要現實得多。 在您的IDE中打開/form-auth文件夾。
build.gradle文件是相同的。 Application.java和WebController.java文件也是如此。 唯一的重大更改是在SecurityConfiguration.java文件中(并且在此文件中,僅一行已更改)。
src/main/java/com/okta/springsecurityauth/SecurityConfiguration.java :
package com.okta.springsecurityauth; ... @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin(); //See how ridiculously simple Spring is making things for us. All you had to do was change the?httpBasic()?fluent method to?formLogin()?and Spring Boot automatically generates a login form for you.
Run it using?./gradlew bootRun .
You’ll see the auto-generated Spring Boot login form.
但是,如果您想樣式化自己的自定義表單而不是使用Spring生成的表單,該怎么辦? 沒有太多的工作了。
首先,將Thymeleaf依賴項添加到build.gradle文件中:
dependencies { ...implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' ... }使用兩個新的控制器方法更新WebController.java文件:
package com.okta.springsecurityauth; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class WebController { @RequestMapping("/") @ResponseBody public String index() { return "You made it!"; } @RequestMapping("/login.html") public String login() { return "login.html"; } @RequestMapping("/login-error.html") public String loginError(Model model) { model.addAttribute("loginError", true); return "login.html"; } }請注意,/ /login-error.html路徑使用與/login.html路徑相同的模板,但向Model添加了loginError屬性。 這只是處理錯誤的一種方式。
另外,請注意,新的控制器方法沒有@ResponseBody批注。 這與新的Thymeleaf依賴性相結合,意味著這些方法將返回要呈現的模板的名稱(與原始響應相反)。 默認情況下,假定模板位于src/main/resources/templates文件夾中。
添加一個新文件: src/main/resources/templates/login.html :
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Login page</title> <style> #container { padding-top:50px; width:400px; margin: 0 auto; font-size:1.5rem; } input { width: 100%; display:block; padding: 5px; font-size: 1.1rem; box-sizing: border-box; } label { margin-top:10px; display:block; } #submit, #submit:focus { margin-top: 20px; border-radius: 8px; padding: 10px; color: white; background-color: #2084ba; border: none; } .error { color: white; background-color: indianred; opacity: 0.7; padding: 10px; width: 100%; text-align: center; box-sizing: border-box; border-radius: 8px; } </style> </head> <body> <div id="container"> <h2>Login page</h2> <form th:action="@{/login.html}" method="post"> <label for="username">User</label> <input type="text" id="username" name="username" autofocus="autofocus" /> <label for="password">Pass</label> <input type="password" id="password" name="password" /> <input id="submit" type="submit" value="Log in" /> </form> <p th:if="${loginError}" class="error">There was a problem logging you in</p> </div> </body> </html>這是用于登錄頁面的Thymeleaf模板文件。 Thymeleaf是與Spring Boot一起使用的標準模板系統。 這是一個功能齊全的模板系統,具有大量功能。 查看項目網站以獲取更多信息。
您需要做的最后更改是更新SecurityController.java文件中的configure(HttpSecurity http)方法:
package com.okta.springsecurityauth; ... @Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login.html") .failureUrl("/login-error.html") .permitAll(); } ... }添加了以下三行:
.loginPage("/login.html") .failureUrl("/login-error.html") .permitAll();它們定義了自定義登錄端點,登錄錯誤端點,并指示Spring Security允??許對這些端點的所有請求。
使用./gradlew bootRun再次運行該應用程序。
這次,您將看到自定義登錄表單。
(幾乎)是SAML時間!
Spring Security SAML擴展目前正在不斷變化。 有一些非官方的2.x發行版可以運行,但是沒有得到官方的支持。
從Spring Security SAML GitHub頁面 :
該項目正在被重寫。 有一個在一個基實現發展 ,包括在里程碑版本里程碑庫。
在development-3.0分支中,我們正在創建一個在里程碑之上構建的解決方案,并與Spring Security更好地保持一致。 該分支的目的是將其與Spring Security項目合并,并作為Spring Security核心的一部分發布。
因此,我們將不會發布2.0.0里程碑的任何正式版本,但將對其進行維護,直到該里程碑中存在的所有功能都屬于Spring Security。
如果您想冒險進入Spring Boot SAML的當前狀態, Spring SAML Extension Docs是一個不錯的起點。
Okta的Matt Raible也提供了一個很棒的教程 ,說明如何使用Spring Boot 1.x實現SAML。
Vincenzo De Notari提供了一個使用SAML 2.0和Spring Boot 2.1.3 的示例服務提供程序實現 。
注意:如果要使用Okta測試SAML,則需要請求Okta企業版試用。
添加OAuth 2.0 + OpenID Connect身份驗證
進入developer.okta.com儀表板后,創建一個OIDC應用程序:
- 在頂部菜單中,單擊“ 應用程序”
- 單擊綠色的添加應用程序按鈕
- 單擊“ Web應用程序類型”,然后單擊“下一步”。
- 為應用命名 。 任何名字。
- 將登錄重定向URI設置為http://localhost:8080/login/oauth2/code/okta
- 單擊完成 。
記下頁面底部的客戶端ID和客戶端密鑰 。 您將需要這些。
大! 這就是將Okta配置為OIDC提供程序所要做的。
從示例存儲庫中打開oauth-okta目錄。
在執行其他任何操作之前,您需要更新src/main/resources/application.yml文件。 您需要填寫三個值:
接下來,查看build.gradle文件的dependencies部分。
dependencies { implementation 'com.okta.spring:okta-spring-boot-starter:1.2.0' implementation 'org.springframework.boot:spring-boot-starter-web' ... }您會注意到一個新的依賴項,并且不再需要spring-boot-starter-security :
- okta-spring-boot-starter
Okta Spring Boot Starter是Okta的擴展,它簡化了與OAuth和Spring Security相關的某些依賴項管理和配置。 您可以查看項目GitHub頁面以獲取更多信息。
老實說,該項目的其余部分非常簡單。 Application.java文件是相同的。
WebController.java文件添加了一些新方法。 實際上,這可能與前幾個示例相同,只是返回了一個字符串,但是我認為演示如何訪問某些經過身份驗證的用戶信息會很好。
package com.okta.springsecurityauth; ... @Controller public class WebController {@RequestMapping("/")@ResponseBodypublic String home(@AuthenticationPrincipal OidcUser oidcUser) {return "Welcome, " + oidcUser.getFullName();}@RequestMapping("/attributes")@ResponseBodypublic String attributes(@AuthenticationPrincipal OidcUser oidcUser) {return oidcUser.getAttributes().toString();}@RequestMapping("/authorities")@ResponseBodypublic String authorities(@AuthenticationPrincipal OidcUser oidcUser) {return oidcUser.getAuthorities().toString();}}/ home端點返回歡迎消息和OIDC用戶的全名。
/attributes端點返回應用程序從Okta接收到的用戶屬性。
/authorities端點返回用戶權限(角色和作用域)。 這些必須與授權有關,以定義允許用戶執行的動作或用戶可以訪問和修改的資源。
您會注意到沒有SecurityConfiguration.java文件。 在這個簡單的示例中,這是不必要的,因為OAuth是默認的身份驗證方案,默認情況下,所有路徑都需要身份驗證(這就是我們想要的)。
大! 現在嘗試一下。 使用./gradlew bootRun在oauth-okta ./gradlew bootRun目錄中運行該應用程序。
導航到http://localhost:8080/ 。
如果您想查看Okta的托管登錄屏幕,則可能需要使用隱身窗口或退出Okta開發人員儀表板。
使用Okta登錄名登錄,您將被帶到一個類似以下內容的屏幕:
Welcome, Andrew Hughes您也可以嘗試使用http://localhost:8080/attributes端點和http://localhost:8080/authorities端點。
通過身份驗證完成Spring Boot + Spring Security App
在本教程中,您介紹了一些Spring Boot和Spring Security身份驗證方法。 您從HTTP基礎開始; 使用自動生成的表單進入基于表單的身份驗證; 然后自定義應用程序以將Thymeleaf模板用于登錄表單。 接下來,您使用Okta和Spring Boot實現了OAuth / OIDC單一登錄應用程序。
您可以在GitHub上的本教程中找到所有示例的源代碼。
如果您想了解有關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頁面 。
如果您對此帖子有任何疑問,請在下面添加評論。 有關更多精彩內容, 請在Twitter上關注@oktadev , 在Facebook上關注我們,或訂閱我們的YouTube頻道 。
“具有Spring Security的簡單身份驗證”最初于2019年5月31日發布在Okta Developer博客上。
朋友不允許朋友寫用戶身份驗證。 厭倦了管理自己的用戶? 立即嘗試Okta的API和Java SDK。 在幾分鐘之內即可對任何應用程序中的用戶進行身份驗證,管理和保護。
翻譯自: https://www.javacodegeeks.com/2019/07/simple-authentication-spring-security.html
總結
以上是生活随笔為你收集整理的使用Spring Security进行简单身份验证的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 经办人是指谁 经办人简单介绍
- 下一篇: jboss fuse 教程_在JBoss