尝试在Spring MVC中使用OAuth保护资源 [英] Trying to protect resources with OAuth in Spring MVC

查看:129
本文介绍了尝试在Spring MVC中使用OAuth保护资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们已经在Spring MVC上使用Java编写了REST Web服务,我一直在尝试保护它们。

We already have REST web services written in Java on Spring MVC and I have been trying to protect them.

OAuth服务器在另一个处理登录和创建访问令牌。因此,我需要在授予用户访问Web服务的权限之前验证访问令牌是否正确。

The OAuth server is implemented in another website which handles the logging in and creation of the Access Token. I need therefore to verify that the access token is correct before giving the users access to the webservices.

但是,使用OAuth的Spring Security文档看起来确实很差,并且示例代码实际上并没有解释它在做什么!我甚至不确定我是否应该为此实现它,因为它应该是这么简单的检查。

However the documentation for Spring Security with OAuth seems to be really poor, and the example code doesn't actually explain what it is doing! I am not even sure if I should be implementing it for this, as it should be such a simple check.

保护这些Web服务的最佳方法是什么?什么是最好的入门方式?

What is the best way to go about protecting these web services? And what is the best way to get started?

感谢您的帮助。

推荐答案

重要



Important

这个答案假设OAuth服务器是在另一个处理登录和创建访问令牌的网站中实现的。您的意思是您在不属于您自己的单独网站上使用服务。

This answer assumes that by "The OAuth server is implemented in another website which handles the logging in and creation of the Access Token." You mean that you are consuming a service on a separate site that is not your own.


我当然可以解决你的文档问题。 Spring Security可以说是任何Spring项目中最陡峭的学习曲线,OAuth支持相当新,并且与Spring Security分开维护。 Spring Security OAuth文档 稀疏。

I can certainly relate to your documentation woes. Spring Security has arguably the steepest learning curve of any Spring project, and OAuth support is fairly new and maintained separately from Spring Security. The Spring Security OAuth docs are sparse.

如果你对OAuth没有好感,那就去买一个吧! / strong>您要求您的用户信任您网站实施此标准的安全性。因此,您无法理解您对该主题的理解!显而易见的起点是 OAuth.net OAuth初学者指南

如果/您对OAuth的工作方式有一个良好的感觉,我强烈推荐阅读Spring Security使用入门文章和教程文档列表,以便更好地了解Spring Security的实现方式一般来说。

If/Once you have a good feel for how OAuth works, I'd highly recommend reading through the Spring Security "Getting Started" and "Articles and Tutorials" documentation lists to get a good feel for how Spring Security is implemented in general.

一旦你对Spring Security有了不错的了解并且对OAuth有了不错的了解,官方的Spring Security OAuth 用户指南 将开始有意义。您将特别关注正在使用的OAuth版本的消费者/客户端部分( 1.0 2.0 )。

Once you have a decent knowledge of Spring Security and a decent knowledge of OAuth, the official Spring Security OAuth user guide will start to make sense. You'll want to pay attention particularly the Consumer/Client sections for the version of OAuth you're working with (1.0 or 2.0).

同一网站也有一个不错的 教程 基于第二部分上面提到的 OAuth初学者指南服务。

That same site also has a decent tutorial for both OAuth 1.0 and OAuth 2.0 which is based on the second section of the services OAuth Beginner's Guide mentioned above.

对于您的问题,我们将重点关注从 教程 。此服务打印的照片是由外部网站托管的受OAuth保护的资源。 Tonr推迟到这些站点访问这些资源。这将包括重定向用户以进行用户身份验证和身份验证确认(如果有必要)。

For your problem we're going to focus on the implementation of the Tonr photo printing service from the tutorial mentioned above. This service prints photos which are OAuth protected resources hosted by external sites. Tonr defers to these sites for access control of these resources. This will include redirecting the user for user authentication and authentication confirmation if necessary.

Spring-MVC REST服务/控制器本身是外部OAuth受保护资源的消费者实现此延迟通过使用请求过滤器授权(我的术语)行为。根据1.0 用户指南

Spring-MVC REST services/controllers which are themselves consumers of external OAuth protected resources implement this "deferred authorization" (my term) behavior through the use of request filters. Per the 1.0 user guide:


有两个请求过滤器,
适用于OAuth使用者
逻辑。第一个过滤器,
OAuthConsumerContextFilter ,是
,负责建立
OAuth特定的安全上下文,非常类似于Spring Security的
。 springsource.org/spring-security/oauth/oauth1.html#SecurityContextrel =noreferrer> SecurityContext 。安全上下文
只包含一组为
当前用户获取的访问令牌
。在向
受保护资源发出请求时,此安全上下文是

There are two request filters that are applicable to the OAuth consumer logic. The first filter, OAuthConsumerContextFilter, is responsible for establishing an OAuth-specific security context, very similar to Spring Security's SecurityContext. The security context simply contains a set of access tokens that have been obtained for the current user. This security context is leveraged when making requests for protected resources.

还有另一个请求过滤器,
OAuthConsumerProcessingFilter
可以应用于需要访问
远程受保护资源的特定URL或URL
模式。在Spring Security的
过滤器链中放置
此过滤器将确保在允许访问资源的
之前获得指定的
URL模式所需的任何
访问令牌。

There is another request filter, OAuthConsumerProcessingFilter, that can be applied to specific URLs or URL patterns that require access to a remote protected resource. Putting this filter in Spring Security's filter chain will ensure that any access tokens needed for the specified URL patters will be obtained before allowing access to the resources.

正如您所看到的,对于OAuth 1.0,使用有效的 OAuthConsumerProcessingFilter 将处理获取有效访问令牌的所有内容,并在访问被拒绝时通知用户。同样有相应的 OAuth2ClientContextFilter OAuth2ClientProcessingFilter 类。

So as you can see, for OAuth 1.0, filtering requests with a valid OAuthConsumerProcessingFilter will handle everything surrounding acquiring valid Access Tokens, as well as notifying the user when access is denied. Likewise there is are corresponding OAuth2ClientContextFilter and OAuth2ClientProcessingFilter classes.

最后,一旦这是设置完成后,您可以使用 OAuthRestTemplate OAuth2RestTemplate 访问控制器中受OAuth保护的资源,就像访问不受保护的资源一样正常 RestTemplate (info 这里)。但是,它们必须通过 ProtectedResourceDetails OAuth2ProtectedResourceDetails

Finally, once this is all set up you can access OAuth protected resources in your controllers with OAuthRestTemplate or OAuth2RestTemplate just like you would access unprotected resources with the normal RestTemplate (info here). However they must be injected into your service or controller with an instance of ProtectedResourceDetails or OAuth2ProtectedResourceDetails.

如果这听起来很复杂,我有个好消息。所有这些废话通常都是抽象的,并由OAuth和OAuth2 XML命名空间为您处理

I have good news if this sounds complex. All of this nonsense is typically abstracted away and handled for you by the OAuth and OAuth2 XML Namespaces

oauth命名空间在位于其中的Tonr教程的XML配置文件中进行了演示。各自的src / webapp / WEB-INF目录。以下示例直接从那里缩写。

The oauth namespace is demonstrated in the Tonr tutorials' XML config files located in their respective src/webapp/WEB-INF directories. The examples below are abbreviated directly from there.

如果您想了解提供者方如何在没有使用OAuth名称空间的情况下工作,我'建议您查看此SpringSource论坛帖子,并按照问题进行操作 SECOAUTH-53 了解更新。

If you'd like to see how the provider side works without using OAuth namespaces, I'd suggest you check this SpringSource forum post, and follow the issue SECOAUTH-53 for updates.

此处Tonr正在使用Sparklr和Google的OAuth保护服务,因此设置了 ProtectedResourceDetailsS​​ervice 使用 oauth:resource-details-service 标记调用 resourceDetails 。然后设置 OAuthConsumerContextFilter OAuthConsumerProcessingFilter ,并引用 resourceDetails 使用 oauth:consumer 标记。使用 oauth:resource 标记为每个受保护资源提供程序创建了 ProtectedResourceDetails 的实例。

Tonr is consuming OAuth protected services from both Sparklr and Google here, so it sets up a ProtectedResourceDetailsService called resourceDetails using the oauth:resource-details-service tag. It then sets up the OAuthConsumerContextFilter and OAuthConsumerProcessingFilter with a reference to resourceDetails by using the oauth:consumer tag. These filters are created with instances of ProtectedResourceDetails for each of the protected resource providers by using the oauth:resource tag.



来自tonr的applicationContext.xml:


From tonr's applicationContext.xml:

<oauth:consumer resource-details-service-ref="resourceDetails" oauth-failure-page="/oauth_error.jsp">
  <oauth:url pattern="/sparklr/**" resources="sparklrPhotos"/>
  <oauth:url pattern="/google/**" resources="google"/>
</oauth:consumer>

<oauth:resource-details-service id="resourceDetails">
  <oauth:resource id="sparklrPhotos"
                  key="tonr-consumer-key"
                  secret="SHHHHH!!!!!!!!!!"
                  request-token-url="http://localhost:8080/sparklr/oauth/request_token"
                  user-authorization-url="http://localhost:8080/sparklr/oauth/confirm_access"
                  access-token-url="http://localhost:8080/sparklr/oauth/access_token"/>
  <!--see http://code.google.com/apis/accounts/docs/OAuth_ref.html-->
  <oauth:resource id="google" key="anonymous" secret="anonymous"
                  request-token-url="https://www.google.com/accounts/OAuthGetRequestToken"
                  user-authorization-url="https://www.google.com/accounts/OAuthAuthorizeToken"
                  access-token-url="https://www.google.com/accounts/OAuthGetAccessToken"
                  request-token-method="GET"
                  access-token-method="GET">
    <oauth:addtionalParameter name="scope" value="https://picasaweb.google.com/data/"/>
    <oauth:addtionalParameter name="xoauth_displayname" value="Tonr Example Application"/>
  </oauth:resource>
</oauth:resource-details-service>



下一步 sparklrService googleService 创建bean,每个bean都有自己的内部 OAuthRestTemplate bean,每个bean都带有一个引用通过 constructor-arg 到相应的 ProtectedResourceDetails 之前创建并注入 ProtectedResourceDetailsS​​ervice bean。


Next the sparklrService and googleService beans are created, each with their own internal OAuthRestTemplate bean, each which is provided with a reference via constructor-arg to the respective ProtectedResourceDetails which were created previously and injected into the ProtectedResourceDetailsService bean.



来自tonr的spring-servlet.xml:


From tonr's spring-servlet.xml:

<bean id="sparklrService" class="org.springframework.security.oauth.examples.tonr.impl.SparklrServiceImpl">
  <property name="sparklrPhotoListURL" value="${sparklrPhotoListURL}"/>
  <property name="sparklrPhotoURLPattern" value="${sparklrPhotoURLPattern}"/>
  <property name="sparklrRestTemplate">
    <bean class="org.springframework.security.oauth.consumer.OAuthRestTemplate">
      <constructor-arg ref="sparklrPhotos"/>
    </bean>
  </property>

</bean>
<bean id="googleService" class="org.springframework.security.oauth.examples.tonr.impl.GoogleServiceImpl">
  <property name="googleRestTemplate">
    <bean class="org.springframework.security.oauth.consumer.OAuthRestTemplate">
      <constructor-arg ref="google"/>
    </bean>
  </property>

</bean>


我的理解在这里稍微弱一些。部分原因是OAuth2名称空间似乎抽象了更多。此外,看起来Tonr 2的例子还没有像原来的Tonr那样充实。我会尽我所能并在必要时进行编辑。

My understanding is a little bit weaker here. Part of the reason for this is that the OAuth2 namespace appears to abstract away a lot more. Also, it looks like the Tonr 2 example hasn't been fleshed out as well as the original Tonr example. I'll do my best and edit if necessary.

首先创建一个 oauth:client 标签并给出一个引用 InMemoryOAuth2ClientTokenServices bean。看来这会设置适当的过滤器。然后使用 oauth:resource 为sparklr和Facebook创建 OAuth2ProtectedResourceDetails bean。

First an oauth:client tag is created and given a reference to an InMemoryOAuth2ClientTokenServices bean. It appears that this sets up the appropriate filters. Then OAuth2ProtectedResourceDetails beans are created for both sparklr and Facebook with the oauth:resource.



来自tonr 2的applicationContext.xml:


From tonr 2's applicationContext.xml:

<!--apply the oauth client context-->
<oauth:client token-services-ref="oauth2TokenServices"/>

<beans:bean id="oauth2TokenServices" class="org.springframework.security.oauth2.consumer.token.InMemoryOAuth2ClientTokenServices"/>

<!--define an oauth 2 resource for sparklr-->
<oauth:resource id="sparklr" type="authorization_code" clientId="tonr"
                  accessTokenUri="http://localhost:8080/sparklr/oauth/authorize"
                  userAuthorizationUri="http://localhost:8080/sparklr/oauth/user/authorize"/>

<!--define an oauth 2 resource for facebook. according to the facebook docs, the 'clientId' is the App ID, and the 'clientSecret' is the App Secret -->
<oauth:resource id="facebook" type="authorization_code" clientId="162646850439461" clientSecret="560ad91d992d60298ae6c7f717c8fc93"
                  bearerTokenMethod="query" accessTokenUri="https://graph.facebook.com/oauth/access_token"
                  userAuthorizationUri="https://www.facebook.com/dialog/oauth"/>



接下来,就像前面的例子中的每个控制器或服务bean一样需要访问受保护资源的内容是使用内部 OAuth2RestTemplate bean创建的。这个内部bean通过 constructor-arg 给出了正确的 OAuth2ProtectedResourceDetails bean的引用。


Next, just like in the previous example each controller or service bean which needs access to a protected resource is created with an internal OAuth2RestTemplate bean. This internal bean is given a reference to the correct OAuth2ProtectedResourceDetails bean via constructor-arg.



来自tonr 2的spring-servlet.xml:


From tonr 2's spring-servlet.xml:

<bean id="facebookController" class="org.springframework.security.oauth.examples.tonr.mvc.FacebookController">
  <!-- snipped irrelevant properties -->
  <property name="facebookRestTemplate">
    <bean class="org.springframework.security.oauth2.consumer.OAuth2RestTemplate">
      <constructor-arg ref="facebook"/>
    </bean>
  </property>
  <property name="tokenServices" ref="oauth2TokenServices"/>
</bean>

<bean id="sparklrService" class="org.springframework.security.oauth.examples.tonr.impl.SparklrServiceImpl">
  <!-- snipped irrelevant properties -->
  <property name="sparklrRestTemplate">
    <bean class="org.springframework.security.oauth2.consumer.OAuth2RestTemplate">
      <constructor-arg ref="sparklr"/>
    </bean>
  </property>
  <property name="tokenServices" ref="oauth2TokenServices"/>
</bean>

这篇关于尝试在Spring MVC中使用OAuth保护资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆