javascript
使用带有OAuth的Spring Security保护资源
1.簡介
在本教程中,我們將研究如何使用Spring Security和OAuth來基于路徑模式( / api / ** )保護服務(wù)器上的管理資源。 我們配置的另一個路徑模式( / oauth / token )將幫助已配置的授權(quán)服務(wù)器生成訪問令牌。 請注意,我們將在此演示應(yīng)用程序中使用“ 密碼授予類型” 。
在繼續(xù)實施之前,讓我們回顧一下與該授予類型有關(guān)的事件。
2.資源所有者密碼憑證授予類型
- 在受信任的應(yīng)用程序之間使用。
- 用戶(資源所有者)直接與客戶端應(yīng)用程序共享憑據(jù),客戶端應(yīng)用程序在成功驗證用戶憑據(jù)并進一步授權(quán)用戶訪問服務(wù)器上的有限資源后,請求授權(quán)服務(wù)器返回訪問令牌。
有用的鏈接
- 了解有關(guān)其他授權(quán)授予類型的更多信息
- 了解OAuth2令牌認證
3.實施
確保將所需的pom條目正確添加到pom.xml文件中。
pom.xml
<!-- Spring dependencies --> <dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${springframework.version}</version> </dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${springframework.version}</version> </dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${springframework.version}</version> </dependency><!-- Spring Security Dependencies --> <dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-core</artifactId><version>${spring-security.version}</version> </dependency> <dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-web</artifactId><version>${spring-security.version}</version> </dependency> <dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId><version>${spring-security.version}</version> </dependency> <dependency><groupId>org.springframework.security.oauth</groupId><artifactId>spring-security-oauth2</artifactId><version>${spring-security.oauth.version}</version> </dependency>web.xml
更新web.xml文件以加載上下文文件并配置Spring Security過濾器,該過濾器將在處理請求之前重定向身份驗證和授權(quán)請求。
<web-app xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"version="3.0"><display-name>Archetype Created Web Application</display-name><servlet><servlet-name>mvc-dispatcher</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>mvc-dispatcher</servlet-name><url-pattern>/</url-pattern></servlet-mapping><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- Loads context files --><context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/mvc-dispatcher-servlet.xml,/WEB-INF/spring-security.xml</param-value></context-param><!-- Spring Security --><filter><filter-name>springSecurityFilterChain</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class></filter><filter-mapping><filter-name>springSecurityFilterChain</filter-name><url-pattern>/*</url-pattern></filter-mapping> </web-app>mvc-dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"><context:component-scan base-package="com.jcombat" /><mvc:annotation-driven /><beanclass="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix"><value>/WEB-INF/pages/</value></property><property name="suffix"><value>.jsp</value></property></bean> </beans>由于我們將使用admin JSP文件,因此我們已經(jīng)為其配置了相應(yīng)的視圖解析器。
現(xiàn)在,讓我們在其上下文文件中配置Spring Security OAuth。
spring-security.xml
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oauth="http://www.springframework.org/schema/security/oauth2"xmlns:context="http://www.springframework.org/schema/context"xmlns:sec="http://www.springframework.org/schema/security" xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd "><!-- Default url to get a token from OAuth --><http pattern="/oauth/token" create-session="stateless"authentication-manager-ref="clientAuthenticationManager"xmlns="http://www.springframework.org/schema/security"><intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" /><anonymous enabled="false" /><http-basic entry-point-ref="clientAuthenticationEntryPoint" /><custom-filter ref="clientCredentialsTokenEndpointFilter"after="BASIC_AUTH_FILTER" /><access-denied-handler ref="oauthAccessDeniedHandler" /></http><!-- URLs should be protected and what roles have access to them --><!-- Can define more patterns based on the protected resources hosted on the server --><http pattern="/api/**" create-session="never"entry-point-ref="oauthAuthenticationEntryPoint"access-decision-manager-ref="accessDecisionManager"xmlns="http://www.springframework.org/schema/security"><anonymous enabled="false" /><intercept-url pattern="/api/**" access="ROLE_APP" /><!-- Protect oauth clients with resource ids --><custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" /><access-denied-handler ref="oauthAccessDeniedHandler" /></http><bean id="oauthAuthenticationEntryPoint"class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"><property name="realmName" value="demo/client" /></bean><bean id="clientAuthenticationEntryPoint"class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"><property name="realmName" value="demo/client" /><property name="typeName" value="Basic" /></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="clientAuthenticationManager" /></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><authentication-manager id="clientAuthenticationManager"xmlns="http://www.springframework.org/schema/security"><authentication-provider user-service-ref="clientDetailsUserService" /></authentication-manager><!-- This is simple authentication manager, with a hard-coded username/password combination. We can replace this with a user defined service to fetch user credentials from DB instead --><authentication-manager alias="authenticationManager"xmlns="http://www.springframework.org/schema/security"><authentication-provider><user-service><user name="admin" password="123" authorities="ROLE_APP" /></user-service></authentication-provider></authentication-manager><bean id="clientDetailsUserService"class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService"><constructor-arg ref="clientDetails" /></bean><!-- This defines the token store. We have currently used in-memory token store but we can instead use a user defined one --><bean id="tokenStore"class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" /><!-- If need to store tokens in DB <bean id="tokenStore"class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore"><constructor-arg ref="jdbcTemplate" /></bean> --><!-- This is where we defined token based configurations, token validity and other things --><bean id="tokenServices"class="org.springframework.security.oauth2.provider.token.DefaultTokenServices"><property name="tokenStore" ref="tokenStore" /><property name="supportRefreshToken" value="true" /><property name="accessTokenValiditySeconds" value="120" /><property name="clientDetailsService" ref="clientDetails" /></bean><bean id="userApprovalHandler"class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler"><property name="tokenServices" ref="tokenServices" /></bean><!-- The server issuing access tokens to the client after successfully authenticating the resource owner and obtaining authorization --><oauth:authorization-serverclient-details-service-ref="clientDetails" token-services-ref="tokenServices"user-approval-handler-ref="userApprovalHandler"><oauth:authorization-code /><oauth:implicit /><oauth:refresh-token /><oauth:client-credentials /><oauth:password /></oauth:authorization-server><!-- Define protected resources hosted by the resource server --><oauth:resource-server id="resourceServerFilter"resource-id="adminProfile" token-services-ref="tokenServices" /><!-- OAuth clients allowed to access the protected resources, can be something like facebook, google if we are sharing any resource with them --><oauth:client-details-service id="clientDetails"><oauth:client client-id="fbApp"authorized-grant-types="password,refresh_token"secret="fbApp" authorities="ROLE_APP" resource-ids="adminProfile" /></oauth:client-details-service><sec:global-method-securitypre-post-annotations="enabled" proxy-target-class="true"><sec:expression-handler ref="oauthExpressionHandler" /></sec:global-method-security><oauth:expression-handler id="oauthExpressionHandler" /><oauth:web-expression-handler id="oauthWebExpressionHandler" /></beans>我們已經(jīng)配置了/ oauth / token URL來發(fā)布訪問和刷新令牌,并且/ api / **映射到服務(wù)器上實際受保護的資源。 因此,要訪問與模式/ api / **匹配的任何URL,需要將有效令牌與請求一起傳遞。
身份驗證管理器是進行身份驗證的容器。 在我們的情況下,身份驗證管理器檢查–
- 用戶是否通過身份驗證。
- 用戶是否請求了正確的客戶ID。
- 如果client-id正確,則該用戶是否有權(quán)使用它來訪問服務(wù)器上的管理配置文件。
請參閱以下代碼段–
<authentication-manager id="clientAuthenticationManager"xmlns="http://www.springframework.org/schema/security"><authentication-provider user-service-ref="clientDetailsUserService" /> </authentication-manager><bean id="clientDetailsUserService"class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService"><constructor-arg ref="clientDetails" /> </bean><!-- OAuth clients allowed to access the protected resources, can be something like facebook, google if we are sharing any resource with them --> <oauth:client-details-service id="clientDetails"><oauth:client client-id="fbApp"authorized-grant-types="password,refresh_token"secret="fbApp" authorities="ROLE_APP" resource-ids="adminProfile" /> </oauth:client-details-service>用戶通過身份驗證后, 授權(quán)服務(wù)器將調(diào)用tokenServices并頒發(fā)訪問令牌。
<oauth:authorization-serverclient-details-service-ref="clientDetails" token-services-ref="tokenServices"user-approval-handler-ref="userApprovalHandler"><oauth:authorization-code /><oauth:implicit /><oauth:refresh-token /><oauth:client-credentials /><oauth:password /> </oauth:authorization-server><bean id="tokenServices"class="org.springframework.security.oauth2.provider.token.DefaultTokenServices"><property name="tokenStore" ref="tokenStore" /><property name="supportRefreshToken" value="true" /><property name="accessTokenValiditySeconds" value="120" /><property name="clientDetailsService" ref="clientDetails" /> </bean><bean id="tokenStore"class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" /><bean id="userApprovalHandler"class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler"><property name="tokenServices" ref="tokenServices" /> </bean>在指定客戶端時,請注意我們指定的授權(quán)類型,即password 。
<oauth:client-details-service id="clientDetails"><oauth:client client-id="fbApp"authorized-grant-types="password,refresh_token"secret="fbApp" authorities="ROLE_APP" resource-ids="adminProfile" /> </oauth:client-details-service>發(fā)出訪問令牌后,我們便可以訪問服務(wù)器上受保護的資源,并將其與每個請求一起傳遞。 最后,讓我們看看我們編寫的Spring Controller –
DemoController.java
package com.jcombat.controller;import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping;@Controller public class DemoController {@RequestMapping("/api/admin")public String getAdminPage() {return "/secured/admin";} }4.運行應(yīng)用程序
要運行該應(yīng)用程序,讓我們首先從授權(quán)服務(wù)器請求訪問令牌-
http:// localhost:8080 / SpringSecurityOAuth / oauth / token? grant_type =密碼和client_id = fbApp& client_secret = fbApp& 用戶名 = admin& 密碼 = 123
{ "access_token":"5c0c1a28-9603-4818-9ebb-6014600c3de9","token_type":"bearer","refresh_token":"ada8a736-3082-4c3d-9cbf-f043ab8f415f","expires_in":119 }生成訪問令牌后,我們準備將其與服務(wù)器上對受保護資源的所有后續(xù)請求一起傳遞。
http:// localhost:8080 / SpringSecurityOAuth / api / admin? access_token = 5c0c1a28-9603-4818-9ebb-6014600c3de9
5.下載代碼
下載源代碼
翻譯自: https://www.javacodegeeks.com/2017/09/securing-resources-using-spring-security-oauth.html
總結(jié)
以上是生活随笔為你收集整理的使用带有OAuth的Spring Security保护资源的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 将旧的wps文档升级(将升级版的WPS改
- 下一篇: 笔记本电脑如何卸载360卫士(电脑的36