Java API 開發中使用 OAuth2 鑑權
在 Java API 的開發中,鑑權是不可避免的問題。 OAuth2 是一種流行的鑑權方式,它透過授權存取來保護 API 資源。本文將介紹如何在 Java API 開發中使用 OAuth2 進行鑑權。
OAuth2 簡介
OAuth2 是一種用於授權的開放標準,它允許使用者授權第三方應用程式存取他們的伺服器資源,而不必分享他們的憑證。 OAuth2 標準包括下列角色:
- Resource Owner:資源擁有者,即使用者;
- Resource Server:資源伺服器,提供資源的伺服器;
- Client:客戶端,即第三方應用程式;
- Authorization Server:授權伺服器,用於頒發存取權杖。
OAuth2 的授權程序包括以下步驟:
- Client 向Authorization Server 發送授權請求;
- Authorization Server 向Resource Owner 請求授權;
- Resource Owner 授權後,Authorization Server 傳送存取權杖給Client;
- Client 使用存取權杖向Resource Server 傳送請求;
- Resource Server 驗證存取權杖並提供資源。
OAuth2 支援多種授權類型,包括授權碼模式、密碼模式、客戶端模式、隱含授權模式等。在 Java API 開發中,通常使用授權碼模式和密碼模式。
OAuth2 授權碼模式
授權碼模式是OAuth2 中最常用的授權類型,它包含以下步驟:
- Client 向Authorization Server 發送授權請求,包括Client ID 和重定向URI;
- Authorization Server 發送登入頁面給Resource Owner,要求Resource Owner 登入並授權;
- Resource Owner 授權後,Authorization Server 向重定向URI 發送授權碼;
- Client 使用授權碼向Authorization Server 發送請求,包括Client ID 和Client Secret;
- Authorization Server 驗證Client ID 和Client Secret,如果正確,頒發存取權令牌給Client;
- Client 使用存取權杖向Resource Server 傳送請求。
在 Java API 開發中,可以使用 Spring Security OAuth2 框架實作授權碼模式的識別碼。
首先,需要在pom.xml 檔案中新增以下相依性:
<dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> <version>2.3.4.RELEASE</version> </dependency>
然後,在Spring MVC 的設定檔中新增以下設定:
<security:http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="authenticationManager" xmlns="http://www.springframework.org/schema/security"> <security:intercept-url pattern="/oauth/token" access="isAuthenticated()" method="POST" /> <security:anonymous enabled="false" /> <security:http-basic entry-point-ref="clientAuthenticationEntryPoint" /> <security:custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" /> <security:access-denied-handler ref="oauthAccessDeniedHandler" /> </security:http> <security:http pattern="/api/**" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint" access-decision-manager-ref="accessDecisionManager" xmlns="http://www.springframework.org/schema/security"> <security:anonymous enabled="false" /> <security:intercept-url pattern="/api/**" access="ROLE_USER" /> <security:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" /> <security:access-denied-handler ref="oauthAccessDeniedHandler" /> </security:http> <bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"> <property name="realmName" value="spring-boot-oauth2" /> <property name="typeName" value="Basic" /> </bean> <bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"> <property name="realmName" value="spring-boot-oauth2" /> <property name="typeName" value="Bearer" /> </bean> <bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" /> <bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter"> <property name="authenticationManager" ref="authenticationManager" /> </bean> <bean id="resourceServerFilter" class="org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter"> <property name="authenticationManager" ref="authenticationManager" /> </bean> <bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased" xmlns="http://www.springframework.org/schema/beans"> <constructor-arg> <list> <bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" /> <bean class="org.springframework.security.access.vote.RoleVoter" /> <bean class="org.springframework.security.access.vote.AuthenticatedVoter" /> </list> </constructor-arg> </bean> <security:authentication-manager id="authenticationManager"> <security:authentication-provider user-service-ref="userDetailsService" /> </security:authentication-manager> <bean id="userDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl"> <property name="dataSource" ref="dataSource" /> </bean>
其中,/ oauth/token 是用來取得存取權杖的路徑,/api/** 是需要進行鑑權的路徑。
使用 OAuth2RestTemplate 發送請求時,需要先取得存取權杖,程式碼如下:
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(client, context); AuthorizationCodeResourceDetails details = (AuthorizationCodeResourceDetails)client.getResource(); AuthorizationCodeAccessTokenProvider provider = new AuthorizationCodeAccessTokenProvider(); Authentication auth = new UsernamePasswordAuthenticationToken(username, password); AccessTokenRequest tokenRequest = provider.createAccessTokenRequest(details, auth); OAuth2AccessToken accessToken = provider.obtainAccessToken(details, tokenRequest); restTemplate.getOAuth2ClientContext().setAccessToken(accessToken);
其中,client 是 OAuth2ProtectedResourceDetails 類型的對象,包含 Client ID 和 Client Secret 等資訊。
OAuth2 密碼模式
密碼模式是OAuth2 中適用於信任客戶端的授權類型,它包含以下步驟:
- Client 向Authorization Server 發送請求,包括Client ID、Client Secret 和Resource Owner 的使用者名稱密碼;
- Authorization Server 驗證Client ID、Client Secret 和使用者名稱密碼,如果正確,請頒發存取權杖給Client;
- Client 使用存取權杖向Resource Server 傳送請求。
在 Java API 開發中,可以使用 Spring Security OAuth2 框架實作密碼模式的識別碼。
首先,需要在pom.xml 檔案中新增以下相依性:
<dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> <version>2.3.4.RELEASE</version> </dependency>
然後,在Spring MVC 的設定檔中新增以下設定:
<security:http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="authenticationManager" xmlns="http://www.springframework.org/schema/security"> <security:intercept-url pattern="/oauth/token" access="isAuthenticated()" method="POST" /> <security:anonymous enabled="false" /> <security:http-basic entry-point-ref="clientAuthenticationEntryPoint" /> <security:custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" /> <security:access-denied-handler ref="oauthAccessDeniedHandler" /> </security:http> <security:http pattern="/api/**" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint" access-decision-manager-ref="accessDecisionManager" xmlns="http://www.springframework.org/schema/security"> <security:anonymous enabled="false" /> <security:intercept-url pattern="/api/**" access="ROLE_USER" /> <security:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" /> <security:access-denied-handler ref="oauthAccessDeniedHandler" /> </security:http> <bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"> <property name="realmName" value="spring-boot-oauth2" /> <property name="typeName" value="Basic" /> </bean> <bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"> <property name="realmName" value="spring-boot-oauth2" /> <property name="typeName" value="Bearer" /> </bean> <bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" /> <bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter"> <property name="authenticationManager" ref="authenticationManager" /> </bean> <bean id="resourceServerFilter" class="org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter"> <property name="authenticationManager" ref="authenticationManager" /> </bean> <bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased" xmlns="http://www.springframework.org/schema/beans"> <constructor-arg> <list> <bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" /> <bean class="org.springframework.security.access.vote.RoleVoter" /> <bean class="org.springframework.security.access.vote.AuthenticatedVoter" /> </list> </constructor-arg> </bean> <security:authentication-manager id="authenticationManager"> <security:authentication-provider user-service-ref="userDetailsService" /> </security:authentication-manager> <bean id="userDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl"> <property name="dataSource" ref="dataSource" /> </bean>
其中,/ oauth/token 是用來取得存取權杖的路徑,/api/** 是需要進行鑑權的路徑。
使用OAuth2RestTemplate 發送請求時,需要先取得存取權杖,程式碼如下:
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(details, new DefaultOAuth2ClientContext()); restTemplate.getOAuth2ClientContext().setAccessToken(accesstoken);
其中,details 是ResourceOwnerPasswordResourceDetails 類型的對象,包含Client ID、Client Secret、使用者名稱和密碼等資訊。
總結
在 Java API 開發中使用 OAuth2 進行鑑權可以保護 API 資源的安全,並且可以讓使用者更方便地授權第三方應用程式存取他們的伺服器資源。本文介紹了 OAuth2 的授權碼模式和密碼模式,並且提供了使用 Spring Security OAuth2 框架實作鑑權的範例程式碼。希望可以對 Java API 開發者有幫助。
以上是Java API 開發中使用 OAuth2 鑑權的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

Java 8引入了Stream API,提供了一種強大且表達力豐富的處理數據集合的方式。然而,使用Stream時,一個常見問題是:如何從forEach操作中中斷或返回? 傳統循環允許提前中斷或返回,但Stream的forEach方法並不直接支持這種方式。本文將解釋原因,並探討在Stream處理系統中實現提前終止的替代方法。 延伸閱讀: Java Stream API改進 理解Stream forEach forEach方法是一個終端操作,它對Stream中的每個元素執行一個操作。它的設計意圖是處

膠囊是一種三維幾何圖形,由一個圓柱體和兩端各一個半球體組成。膠囊的體積可以通過將圓柱體的體積和兩端半球體的體積相加來計算。本教程將討論如何使用不同的方法在Java中計算給定膠囊的體積。 膠囊體積公式 膠囊體積的公式如下: 膠囊體積 = 圓柱體體積 兩個半球體體積 其中, r: 半球體的半徑。 h: 圓柱體的高度(不包括半球體)。 例子 1 輸入 半徑 = 5 單位 高度 = 10 單位 輸出 體積 = 1570.8 立方單位 解釋 使用公式計算體積: 體積 = π × r2 × h (4
