javascript
带有Spring Security的OAuth 2.0快速指南
“我喜歡編寫身份驗證和授權代碼?!??從來沒有Java開發人員。 厭倦了一次又一次地建立相同的登錄屏幕? 嘗試使用Okta API進行托管身份驗證,授權和多因素身份驗證。
在構建Web應用程序時,必須進行身份驗證和授權。 然而,正確地做起來并不容易。 計算機安全是真正的專業。 眾多開發人員晝夜不停地與眾多國際黑客進行對抗,從而創建了一個持續的開發周期,以發現漏洞,進行攻擊并加以修復。 跟上所有這些獨奏會很痛苦(如果不是不可能的話)。
幸運的是,沒有必要。 Spring Security和Spring Boot使使用OAuth 2.0實施Web應用程序變得非常簡單。 Okta是一種軟件即服務的身份訪問提供商,它在Spring Boot的基礎上構建,以使該過程更加容易。
在本教程中,您將首先使用Spring Boot和Spring Security構建OAuth 2.0 Web應用程序和身份驗證服務器。 之后,您將使用Okta擺脫自我托管的身份驗證服務器,并進一步簡化Spring Boot應用程序。
讓我們開始吧!
創建一個OAuth 2.0服務器
首先轉到Spring Initializr并使用以下設置創建一個新項目:
- 將項目類型從Maven更改為Gradle 。
- 將組更改為com.okta.spring 。
- 將工件更改為AuthorizationServerApplication 。
- 添加一個依賴項: Web 。
下載項目并將其復制到硬盤上有意義的位置。 在本教程中,您將創建三個不同的項目,因此您可能需要創建一個父目錄,例如SpringBootOAuth 。
您需要向build.gradle文件添加一個依賴build.gradle :
implementation 'org.springframework.security.oauth:spring-security-oauth2:2.3.3.RELEASE'這增加了Spring的OAuth優勢。
更新src/main/resources/application.properties以使其匹配:
server.port=8081 server.servlet.context-path=/auth user.oauth.clientId=R2dpxQ3vPrtfgF72 user.oauth.clientSecret=fDw7Mpkk5czHNuSRtmhGmAGL42CaxQB9 user.oauth.redirectUris=http://localhost:8082/login/oauth2/code/ user.oauth.user.username=Andrew user.oauth.user.password=abcd這將設置服務器端口,servlet上下文路徑以及服務器將返回給客戶端的內存中臨時生成的令牌以及我們用戶的用戶名和密碼的一些默認值。 在生產中,對于真正的身份驗證服務器,您將需要更多的復雜后端,而沒有硬編碼的重定向URI,用戶名和密碼。
更新AuthorizationServerApplication類以添加@EnableResourceServer :
package com.okta.spring.AuthorizationServerApplication;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;@SpringBootApplication @EnableResourceServer public class AuthorizationServerApplication {public static void main(String[] args) {SpringApplication.run(AuthorizationServerApplication.class, args);} }在與src/main/java下的應用程序類com.okta.spring.AuthorizationServerApplication相同的包中創建一個新的AuthServerConfig類(從現在開始,請在src/main/java/com/okta/spring/AuthorizationServerApplication創建Java類)。 此Spring配置類啟用并配置OAuth授權服務器。
package com.okta.spring.AuthorizationServerApplication;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;@Configuration @EnableAuthorizationServer public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {@Value("${user.oauth.clientId}")private String ClientID;@Value("${user.oauth.clientSecret}")private String ClientSecret;@Value("${user.oauth.redirectUris}")private String RedirectURLs;private final PasswordEncoder passwordEncoder;public AuthServerConfig(PasswordEncoder passwordEncoder) {this.passwordEncoder = passwordEncoder;}@Overridepublic void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {oauthServer.tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");}@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {clients.inMemory().withClient(ClientID).secret(passwordEncoder.encode(ClientSecret)).authorizedGrantTypes("authorization_code").scopes("user_info").autoApprove(true).redirectUris(RedirectURLs);} }AuthServerConfig類是在客戶端正確進行身份驗證時將創建并返回JSON Web令牌的類。
創建一個SecurityConfiguration類:
package com.okta.spring.AuthorizationServerApplication;import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; 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; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;@Configuration @Order(1) public class SecurityConfiguration extends WebSecurityConfigurerAdapter {@Value("${user.oauth.user.username}")private String username;@Value("${user.oauth.user.password}")private String password;@Overrideprotected void configure(HttpSecurity http) throws Exception {http.requestMatchers().antMatchers("/login", "/oauth/authorize").and().authorizeRequests().anyRequest().authenticated().and().formLogin().permitAll();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser(username).password(passwordEncoder().encode(password)).roles("USER");}@Beanpublic BCryptPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();} }SecurityConfiguration類是實際驗證對授權服務器的請求的類。 注意頂部附近是從application.properties文件中提取用戶名和密碼的地方。
最后,創建一個名為UserController的Java類:
package com.okta.spring.AuthorizationServerApplication;import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;import java.security.Principal;@RestController public class UserController {@GetMapping("/user/me")public Principal user(Principal principal) {return principal;} }此文件允許客戶端應用程序查找有關通過服務器進行身份驗證的用戶的更多信息。
那就是你的資源服務器! 還不錯 Spring Boot使其非常容易。 四個文件和一些屬性。 稍后,您將使用Okta使其變得更加簡單,但是目前,繼續創建可用于測試身份驗證服務器的客戶端應用程序。
啟動授權服務器:
./gradlew bootRun等待它完成運行。 終端應該以這樣的結尾:
... 2019-02-23 19:06:49.122 INFO 54333 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8081 (http) with context path '/auth ' 2019-02-23 19:06:49.128 INFO 54333 --- [ main] c.o.s.A.AuthorizationServerApplication : Started AuthorizationServerApplication in 3.502 seconds (JVM running for 3.945)注意:如果收到有關JAXB的錯誤( java.lang.ClassNotFoundException: javax.xml.bind.JAXBException ),那是因為您正在使用build.gradle 。要解決此問題,請將JAXB添加到build.gradle 。
implementation 'org.glassfish.jaxb:jaxb-runtime'構建您的客戶端應用
回到Spring Initializr 。 使用以下設置創建一個新項目:
- 項目類型應為Gradle (不是Maven)。
- 組: com.okta.spring 。
- 工件: SpringBootOAuthClient 。
- 添加三個依賴項: Web , Thymeleaf , OAuth2 Client 。
下載項目,將其復制到最終的放置位置,然后解壓縮它。
這次您需要將以下依賴項添加到build.gradle文件中:
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.0.4.RELEASE'將src/main/resources/application.properties重命名為application.yml并更新它以匹配以下YAML:
server:port: 8082session:cookie:name: UISESSION spring:thymeleaf:cache: falsesecurity:oauth2:client:registration:custom-client:client-id: R2dpxQ3vPrtfgF72client-secret: fDw7Mpkk5czHNuSRtmhGmAGL42CaxQB9client-name: Auth Serverscope: user_infoprovider: custom-providerredirect-uri-template: http://localhost:8082/login/oauth2/code/client-authentication-method: basicauthorization-grant-type: authorization_codeprovider:custom-provider:token-uri: http://localhost:8081/auth/oauth/tokenauthorization-uri: http://localhost:8081/auth/oauth/authorizeuser-info-uri: http://localhost:8081/auth/user/meuser-name-attribute: name請注意,這里您正在配置clientId和clientSecret以及身份驗證服務器的各種URI。 這些需要匹配另一個項目中的值。
更新SpringBootOAuthClientApplication類以匹配:
package com.okta.spring.SpringBootOAuthClient;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication public class SpringBootOAuthClientApplication {public static void main(String[] args) {SpringApplication.run(SpringBootOAuthClientApplication.class, args);} }創建一個名為WebController的新Java類:
package com.okta.spring.SpringBootOAuthClient;import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping;import java.security.Principal;@Controller public class WebController {@RequestMapping("/securedPage")public String securedPage(Model model, Principal principal) {return "securedPage";}@RequestMapping("/")public String index(Model model, Principal principal) {return "index";} }這是將傳入請求映射到Thymeleaf模板文件(您將在幾秒鐘內完成)的控制器。
創建另一個名為SecurityConfiguration Java類:
package com.okta.spring.SpringBootOAuthClient;import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;@Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter {@Overridepublic void configure(HttpSecurity http) throws Exception {http.antMatcher("/**").authorizeRequests().antMatchers("/", "/login**").permitAll().anyRequest().authenticated().and().oauth2Login();} }此類為您的應用程序定義了Spring Security配置:允許本地路徑上的所有請求并要求對所有其他路由進行身份驗證。 它還設置了Spring Boot OAuth登錄流程。
您需要添加的最后一個文件是兩個Thymeleaf模板文件。 全面了解Thymeleaf模板超出了本教程的范圍,但是您可以在其網站上查看更多信息。
模板位于src/main/resources/templates目錄中。 您會在上面的控制器中注意到,它們只是返回路線的字符串。 當Thymeleaf依賴項包含在構建中時,Spring Boot會自動假定您正在從控制器中返回模板文件的名稱,因此該應用程序將在src/main/resources/templates查找帶有返回字符串加號的文件名。 .html 。
創建主頁模板: src/main/resources/templates/index.html :
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Home</title> </head> <body> <h1>Spring Security SSO</h1> <a href="securedPage">Login</a> </body> </html>以及受保護的模板: src/main/resources/templates/securedPage.html :
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Secured Page</title> </head> <body> <h1>Secured Page</h1> <span th:text="${#authentication.name}"></span> </body> </html>我只想指出這一行:
<span th:text="${#authentication.name}"></span>這行將插入已驗證用戶的名稱。 這行是為什么在build.gradle文件中需要org.thymeleaf.extras:thymeleaf-extras-springsecurity5依賴項的build.gradle 。
啟動客戶端應用程序:
./gradlew bootRun等待它完成。 終端應該以這樣的結尾:
... 2019-02-23 19:29:04.448 INFO 54893 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8082 (http) with context path '' 2019-02-23 19:29:04.453 INFO 54893 --- [ main] c.o.s.S.SpringBootOAuthClientApplication : Started SpringBootOAuthClientApplication in 3.911 seconds (JVM running for 4.403)測試資源服務器
在您選擇的瀏覽器中導航至http://localhost:8082/客戶端應用程序。
單擊登錄鏈接。
您將被定向到登錄頁面:
輸入用戶名Andrew和密碼abcd (來自身份驗證服務器的application.properties文件)。
單擊“ 登錄” ,您將進入超級精美的securePage.html模板,其中應顯示“ Secured Page”和“ Andrew”。
大! 有用。 現在,您將使其變得更加簡單。
您可以停止服務器和客戶端Spring Boot應用程序。
創建一個OpenID Connect應用程序
Okta是SaaS(軟件即服務)身份驗證和授權提供者。 我們為開發人員提供免費帳戶,以便他們可以輕松開發OIDC應用程序。 前往developer.okta.com并注冊一個帳戶。 驗證電子郵件后,登錄并執行以下步驟:
- 轉到應用程序 > 添加應用程序 。
- 選擇應用程序類型Web ,然后單擊下一步 。
- 為應用命名。 我將其命名為“ Spring Boot OAuth”。
- 在登錄重定向URI下, 將值更改為http://localhost:8080/login/oauth2/code/okta 。 其余的默認值將起作用。
- 單擊完成 。
讓頁面保持打開狀態,注意客戶端ID和客戶端密鑰 。 稍后您將需要它們。
創建一個新的Spring Boot App
再回到Spring Initializr 。 使用以下設置創建一個新項目:
- 將項目類型從Maven更改為Gradle 。
- 將組更改為com.okta.spring 。
- 將工件更改為OktaOAuthClient 。
- 添加三個依賴項: Web , Thymeleaf , Okta 。
- 單擊生成項目 。
復制項目并將其解壓縮到某個地方。
在build.gradle文件中,添加以下依賴項:
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.0.4.RELEASE'另外,在您到那里時,請注意com.okta.spring:okta-spring-boot-starter:1.1.0依賴com.okta.spring:okta-spring-boot-starter:1.1.0 。 這是Okta Spring Boot Starter。 這是一個方便的項目,可以輕松輕松地將Okta與Spring Boot集成。 有關更多信息,請查看項目的GitHub 。
將src/main/resources/application.properties更改為application.yml并添加以下內容:
server:port: 8080 okta:oauth2:issuer: https://{yourOktaDomain}/oauth2/defaultclient-id: {yourClientId}client-secret: {yourClientSecret} spring:thymeleaf:cache: false請記住,當我說您需要上面的ClientID和Client Secret時 。 好,時間到了。 您需要將它們以及Okta發行者URL填充到文件中。 它看起來像這樣: dev-123456.okta.com 。 您可以在API > 授權服務器下找到它。
在src/main/resources/templates目錄中,您還需要兩個類似的模板文件。 index.html模板文件完全相同,并且可以根據需要復制。 由于您從Okta返回身份驗證信息的方式與您之前構建的簡單身份驗證服務器相比, securedPage.html模板文件略有不同。
創建主頁模板: src/main/resources/templates/index.html :
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Home</title> </head> <body> <h1>Spring Security SSO</h1> <a href="securedPage">Login</a> </body> </html>以及受保護的模板: src/main/resources/templates/securedPage.html :
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Secured Page</title> </head> <body> <h1>Secured Page</h1> <span th:text="${#authentication.principal.attributes.name}">Joe Coder</span> </body> </html>在com.okta.spring.SpringBootOAuth包中創建一個名為WebController的Java類:
package com.okta.spring.OktaOAuthClient;import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping;import java.security.Principal;@Controller public class WebController {@RequestMapping("/securedPage")public String securedPage(Model model, Principal principal) {return "securedPage";}@RequestMapping("/")public String index(Model model, Principal principal) {return "index";} }該類僅創建兩個路由,一個用于本地路由,一個用于安全路由。 同樣,Spring Boot和Thymeleaf會將其自動修改為src/main/resources/templates的兩個模板文件。
最后,創建另一個Java類,名稱為SecurityConfiguration :
package com.okta.spring.OktaOAuthClient;import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;@Configuration public class SecurityConfiguration extends WebSecurityConfigurerAdapter {@Overridepublic void configure(HttpSecurity http) throws Exception {http.antMatcher("/**").authorizeRequests().antMatchers("/").permitAll().anyRequest().authenticated().and().oauth2Login();} }而已! am!
運行由Okta-OAuth支持的客戶端:
./gradlew bootRun您應該看到一堆以結尾的輸出:
... 2019-02-23 20:09:03.465 INFO 55890 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2019-02-23 20:09:03.470 INFO 55890 --- [ main] c.o.s.O.OktaOAuthClientApplication : Started OktaOAuthClientApplication in 3.285 seconds (JVM running for 3.744)導航到http:// localhost:8080 。
單擊登錄按鈕。
這次,您將被帶到Okta登錄頁面。 您可能需要使用隱身瀏覽器或在此處注銷developer.okta.com儀表板,以免跳過登錄頁面并立即定向到安全端點。
登錄,您將看到帶有您的姓名的安全頁面!
了解有關Spring Boot,Spring Security和OAuth 2.0的更多信息
就是這樣。 超級容易。 在上一教程中,您研究了如何使用Spring Boot和Spring Security來實現非常基本的身份驗證服務器和客戶端應用程序。 接下來,您使用Okta使用功能齊全的SSO和OAuth身份驗證制作一個更簡單的客戶端應用程序。
您可以在oktadeveloper / okta-spring-boot-authz-server-example上的GitHub上查看本教程的完整代碼。
如果您想了解有關Spring Boot,OAuth 2.0和Spring Security的更多信息,請查看以下有用的教程:
- Spring Boot,OAuth 2.0和Okta入門
- OAuth到底是什么?
- Spring Security 5.0和OIDC入門
- 身份,聲明和令牌– OpenID Connect入門,第1部分,共3部分
- 使用Spring Boot和GraphQL構建安全的API
如果您對此帖子有任何疑問,請在下面添加評論。 有關更多精彩內容, 請在Twitter上關注@oktadev ,或訂閱我們的YouTube頻道 !
“具有Spring Security的OAuth 2.0快速指南”最初于2019年3月發布在Okta開發者博客上。
“我喜歡編寫身份驗證和授權代碼?!??從來沒有Java開發人員。 厭倦了一次又一次地建立相同的登錄屏幕? 嘗試使用Okta API進行托管身份驗證,授權和多因素身份驗證。
翻譯自: https://www.javacodegeeks.com/2019/03/quick-guide-oauth-spring-security.html
總結
以上是生活随笔為你收集整理的带有Spring Security的OAuth 2.0快速指南的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信号码怎么解绑
- 下一篇: 凉白开是什么水 凉白开的解释