我们已经有在Spring MVC上用Java编写的REST Web服务,我一直在尝试保护它们。
OAuth服务器是在另一个处理访问令牌登录和创建的网站中实现的。因此,在向用户授予对Web服务的访问权限之前,我需要验证访问令牌是否正确。
但是,带有OAuth的Spring Security的文档似乎真的很差,并且示例代码实际上并未解释其作用!我什至不确定是否应该为此实现它,因为它应该是一个简单的检查。
保护这些Web服务的最佳方法是什么?最好的入门方法是什么?
感谢您的帮助。
java大神给出的解决方案
重要
[2012年12月27日编辑:我在下面引用的教程现在抛出404。在github上,该教程有一个稍微更新的版本。我已经删除了看似不好的链接。由于现在缺少的教程是问询者所引用的教程,因此我暂时不作介绍。据我所知,此处包含的信息仍然有用,所以也许有一天我有空的时候会根据新教程重写它。]
该答案假定“通过OAuth服务器在另一个处理访问令牌登录和创建的网站中实现”。您的意思是您正在使用非您自己的单独站点上的服务。
背景
我当然可以与您的文档问题有关。 Spring Security可以说是任何Spring项目中最艰难的学习过程,并且OAuth支持是相当新的,并且与Spring Security分开维护。 Spring Security OAuth文档稀疏。
如果您对OAuth不太满意,那就去买一个!您要让您的用户信任您的站点实施此标准的安全性。因此,您对本主题的理解不会有任何歧义!明显的起点是OAuth.net和huniverse的OAuth Beginner's Guide。
如果/一旦您对OAuth的工作方式有一个很好的了解,我强烈建议您阅读Spring Security的“ Getting Started”和“ Articles and Tutorials”文档列表,以大致了解如何实现Spring Security。
一旦您对Spring Security和OAuth有了不错的了解,正式的Spring Security OAuth user guide就将变得有意义。您需要特别注意要使用的OAuth版本(1.0或2.0)的“客户/客户端”部分。
该站点还基于上述服务tutorial的第二部分为OAuth 1.0和OAuth 2.0提供了不错的OAuth Beginner's Guide。
访问受保护的宁静资源
对于您的问题,我们将重点介绍上述tutorial中Tonr照片打印服务的实现。此服务打印照片,这些照片是由外部站点托管的OAuth保护的资源。 Tonr会根据这些站点的访问控制这些资源。如有必要,这将包括重定向用户以进行用户身份验证和身份验证确认。
Spring-MVC REST服务/控制器本身就是外部OAuth保护的资源的使用者,它通过使用请求过滤器来实现这种“延迟授权”(我的术语)行为。根据1.0 user guide:
有两个请求过滤器
适用于OAuth使用者
逻辑。第一个过滤器
OAuthConsumerContextFilter是
负责建立
特定于OAuth的安全上下文
类似于Spring Security的
SecurityContext。安全上下文
仅包含一组访问令牌
已经获得的
当前用户。此安全上下文是
提出要求时利用
受保护的资源。
还有另一个请求过滤器,
OAuthConsumerProcessingFilter,
可以应用于特定的URL或URL
需要访问
远程受保护的资源。推杆
Spring Security的这个过滤器
过滤链将确保
访问指定令牌所需的令牌
URL模式将在获得之前
允许访问资源。
如您所见,对于OAuth 1.0,使用有效的OAuthConsumerProcessingFilter
过滤请求将处理获取有效访问令牌的所有事宜,并在拒绝访问时通知用户。同样,有对应的OAuth2ClientContextFilter
和OAuth2ClientProcessingFilter
类。
最后,一旦完成所有设置,就可以使用OAuthRestTemplate
或OAuth2RestTemplate
访问控制器中OAuth保护的资源,就像使用普通的RestTemplate
(信息here)访问不受保护的资源一样。但是,必须使用ProtectedResourceDetails或OAuth2ProtectedResourceDetails实例将它们注入到您的服务或控制器中。
如果这听起来很复杂,我有个好消息。通常,所有这些废话都是由OAuth和OAuth2 XML命名空间为您抽象和处理的
oauth名称空间在Tonr教程的XML配置文件中进行了演示,这些文件位于各自的src / webapp / WEB-INF目录中。下面的示例从那里直接缩写。
如果您想了解提供方在不使用OAuth命名空间的情况下的工作方式,建议您检查this SpringSource forum post,并按照问题SECOAUTH-53进行更新。
OAuth 1.0示例
Tonr在这里使用Sparklr和Google的OAuth保护服务,因此它使用ProtectedResourceDetailsService
标记设置了名为resourceDetails
的oauth:resource-details-service
。然后,使用OAuthConsumerContextFilter
标记通过引用OAuthConsumerProcessingFilter
设置resourceDetails
和oauth:consumer
。通过使用ProtectedResourceDetails
标记,为每个受保护资源提供程序的oauth:resource
实例创建这些筛选器。
从tonr的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,每个都有它们自己的内部OAuthRestTemplate
bean,每个bean通过constructor-arg
提供对以前创建并注入到<cc中的各个ProtectedResourceDetails
的引用。 >豆。
从tonr的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>
OAuth 2.0示例
我的理解在这里有些薄弱。造成这种情况的部分原因是OAuth2名称空间似乎抽象了很多。而且,似乎Tonr 2示例和原始Tonr示例一样没有被充实。我会尽力并在必要时进行编辑。
首先,创建一个ProtectedResourceDetailsService
标记,并提供对oauth:client
bean的引用。看来这将设置适当的过滤器。然后,使用InMemoryOAuth2ClientTokenServices
为sparklr和Facebook创建OAuth2ProtectedResourceDetails
bean。
从tonr 2的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都使用内部oauth:resource
Bean创建。通过OAuth2RestTemplate
将此内部bean引用为正确的OAuth2ProtectedResourceDetails
bean。
从tonr 2的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>
页面加载而不是提交时发生struts验证 - java请原谅我;我对Struts有点陌生。我遇到一个问题,即页面加载而不是我实际提交表单时发生了验证。我整天都在论坛上搜寻和搜寻,没有任何运气。我显然做错了一些事情,应该很容易确定,但是我还没有发现问题所在。这是我的struts.xml的片段:<action name="*Test" method="{1}" clas…
DataSourceTransactionManager和JndiObjectFactoryBean和JdbcTemplate的用途是什么? - java以下的用途是什么:org.springframework.jdbc.core.JdbcTemplate org.springframework.jdbc.datasource.DataSourceTransactionManager org.springframework.jndi.JndiObjectFactoryBean <tx:annotatio…
AppCompat不支持当前主题 - java我的应用在Android N上运行正常,但在Android M上的setContentView(R.layout.activity_main)崩溃: Caused by: java.lang.IllegalArgumentException: AppCompat does not support the current theme features: { w…
当回复有时是一个对象有时是一个数组时,如何在使用改造时解析JSON回复? - java我正在使用Retrofit来获取JSON答复。这是我实施的一部分-@GET("/api/report/list") Observable<Bills> listBill(@Query("employee_id") String employeeID); 而条例草案类是-public static class…
java.net.URI.create异常 - javajava.net.URI.create("http://adserver.adtech.de/adlink|3.0") 抛出java.net.URISyntaxException: Illegal character in path at index 32: http://adserver.adtech.de/adlink|3.0 虽然n…