- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
如果我想为一个客户端保护 REST 服务器,那么 spring-security OAuth2 的最小设置是什么?我不想使用任何不必要的设置或实现任何不必要的 bean。也许已经有一个用于 spring-security + OAuth2 的“简单”教程/示例? (虽然我试图避免对此抱有太大希望)
我当前的工作设置(使用 sparklr 上下文中的 copy+past+wtf)感觉太多了:
<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:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2
http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices">
<oauth:client-credentials />
</oauth:authorization-server>
<sec:authentication-manager alias="clientAuthenticationManager">
<sec:authentication-provider user-service-ref="clientDetailsUserService" />
</sec:authentication-manager>
<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" />
<!-- include this only if you need to authenticate clients via request parameters -->
<custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<oauth:resource-server id="resourceServerFilter"
resource-id="rest_server" token-services-ref="tokenServices" />
<oauth:client-details-service id="clientDetails">
<oauth:client client-id="the_client" authorized-grant-types="client_credentials"
authorities="ROLE_RESTREAD" secret="1234567890" />
</oauth:client-details-service>
<http pattern="/**" 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="/rest/**" access="ROLE_RESTREAD" method="GET" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />
<bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore" />
<property name="supportRefreshToken" value="false" />
<property name="clientDetailsService" ref="clientDetails" />
<property name="accessTokenValiditySeconds" value="400000" />
<property name="refreshTokenValiditySeconds" value="0" />
</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>
<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="theRealm" />
</bean>
<bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="theRealm/client" />
<property name="typeName" value="Basic" />
</bean>
<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager" />
</bean>
<bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails" />
</bean>
<bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<sec:global-method-security pre-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>
我已经实现了 authenticationManager (UserDetailsService) 作为实现基本 spring-security 的一部分,以便帐户和角色针对我们的数据库进行持久化。
我没有真正得到的 bean 是:
userApprovalHandler:为什么我需要在 client_credentials 流/授权中获得任何用户批准?看来,sparklr 会覆盖默认的 TokenServicesUserApprovalHandler
以自动批准一个客户端。对于受信任的客户端和服务器之间的通信,我是否也需要这样做?
oauthAuthenticationEntryPoint:sparklr 所做的就是:
<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="sparklr2" />
</bean>
那应该怎么做?
clientCredentialsTokenEndpointFilter它说,只有当我想通过请求参数进行身份验证时,我才应该包含它。所以我想到的是:向我的服务器发送一个 GET(?) 请求,并获取一个 token 并使用该 token 访问资源?所以我在想,对 token 的请求应该包含 secret 作为请求参数..?
资源服务器过滤器在我看来,这表明一个单独的资源服务器?如果我的资源与身份验证提供程序位于同一台服务器上,这将如何应用?
accessDecisionManager我不记得在设置我的自定义 spring-security 实现时必须使用它,为什么我现在要这样做?
感谢您的通读!希望有人能回答我的一些问题..
我已将设置更新为当前的工作状态。我现在可以使用客户端凭据请求访问 token :
$ curl -X -v -d 'client_id=the_client&client_secret=secret&grant_type=client_credentials' -X POST "http://localhost:9090/our-server/oauth/token"
并使用该 token 访问 protected 资源:
$ curl -H "Authorization: Bearer fdashuds-5432fsd5-sdt5s5d-sd5" "http://localhost:9090/our-server/rest/social/content/posts"
感觉还是有很多设置,我的问题仍然存在。另外我想知道这是否是保护可信客户端和 REST 服务器之间通信的正确方法。
除非通过 https 完成,否则对 token 的初始请求仍然感觉不安全,但这就足够了吗?
还有 token 本身呢,我应该给它一个很长的生命周期并将它持久保存在客户端上吗?在任何情况下,这都意味着捕获一个 token 过期异常,然后请求一个新的异常。还是我应该为每个请求握手?刷新 token 呢?我想我在某处读到刷新 token 对于客户端凭据授予类型不安全..?是否有必要将 token 作为 HTTP header 发送,或者我可以更改它吗?我不想为我们的客户端使用 spring-security 客户端堆栈,因为它有一个相当旧的设置(jboss 5),到目前为止我们所做的只是将 REST 通信功能与请求参数集成..
了解更多关于所有 spring-security 设置的信息也会有所帮助,但文档很薄..
将 spring 安全配置更新为我们当前的状态。另外,这是我们的 web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>the-display-name</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>
com.sun.jersey.spi.spring.container.servlet.SpringServlet
</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>base.package.rest</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/servlet-context.xml
</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>contextAttribute</param-name>
<param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.appServlet</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
注意:上面的 spring-security-context.xml 将被 servlet-context 初始化。 spring-context.xml 本身只初始化 bean。(另外:我们的服务器也有一些 View ,所以所有的 rest 资源都在/rest 下运行,因此是 url 模式。但是:总是需要有一个单独的 servlet 和 spring 上下文。)
最佳答案
userApprovalHandler:如果您的系统中只有一个客户端,我同意用户不必批准它访问他们的数据。
oauthAuthenticationEntryPoint:正常情况下,如果认证失败,响应类型为 JSON。文档说“如果身份验证失败并且调用者要求特定的内容类型响应,则此入口点可以发送一个响应,以及标准的 401 状态。”
clientCredentialsTokenEndpointFilter:颁发访问 token 是一个两步过程。首先,您将用户发送到资源服务器进行身份验证。此重定向由客户端验证,理想情况下使用 HTTP header ( key + secret )。作为返回,客户端会获得一个代码,该代码可以换取一个 token 。您不会直接将 key + secret 交易为 token ,因为它不包含用户的批准。
resourceServerFilter:我认为这样做的目的是指示哪些客户端可以访问哪些资源,如果您有许多不同的资源。
accessDecisionManager:对于 OAuth2,你需要一个 ScopeVoter,所以默认的 Manager 不够好。
一般:如果您只有一个客户端代表用户访问资源,那么也许考虑使用 Digest 而不是 OAuth2?如果您只想对客户端(而不是用户)进行身份验证,那么 OAuth2 就太过分了。 OAuth2 中的客户端身份验证实际上与基于 https 的基本身份验证相同。
关于java - 2腿(客户端凭据)oauth2服务器的 Spring 安全上下文设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14138556/
我有一个问题,我不断收到错误 没有为“svn.ssl.server”凭据注册的提供者 我正在使用在另一台 SVN 服务器上工作的相同代码,但我设置的新服务器似乎无法连接,即使我可以通过 Web 浏览器
如何通过 shell 在 Hudson 中输入 subversion 凭据? 我尝试在 HUDSON_HOME 中生成文件 hudson.scm.SubversionSCM.xml 并重新加载配置,但
我正在尝试使用 powershell 访问远程注册表,如下所示: $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachi
我需要将凭据存储在 powershell 中以便多次使用。 StackOverflow 上有很多例子,所以我拿了一个 $tmpCred = Get-Credential $tmpCred.Passwo
我遇到了 youtube java 凭据的问题,通常它运行良好并且我能够上传到 youtube,但今天我收到此异常无效的凭据。 YouTubeService service = new YouTube
我正在阅读中提供的 Hadoop 凭证文档 https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/Crede
我想知道在为 MySQL 凭据/主机创建变量时最佳做法或建议做什么。 define('HOST', 'localhost'); // etc.. mysql_connect(HO
我试图让 Jenkins 从 BitBucket 克隆我的 mercurial 项目。它不会,因为它说凭据有问题 - 好吧,bitbucket 拒绝 Jenkins 提供的任何内容。 我几乎 100%
这里有一百万篇关于如何使用 git 缓存凭据的帖子。但是,如果机器重新启动,它们似乎都不成立。有没有办法缓存在机器重新启动时持续的凭据? 最佳答案 是的,在 Debian 和 Ubuntu 上,您可以
我正在尝试在我的环境中为 IIS 节点使用共享配置,我想使用组托管服务帐户凭据来实现这一目标。 当我将应用程序池的凭据应用为 MyDomain\GmsaAccount$ 时,它运行良好,但是当我尝试在
我创建了一个应用程序,它充当 2 个不同 API(WebEx 和 Exchange Web 服务)和电子邮件之间的桥梁。用户向一个特殊的电子邮件地址发送日历邀请,该应用程序解析 ICS 并创建一个 W
我正在尝试将凭据从 Jenkins 迁移到另一个凭据存储。 我想从 Jenkins 商店读取凭据,并找到了这个脚本 ( https://github.com/tkrzeminski/jenkins-g
我有一个在 Windows 上运行的 Jenkins 服务器。它将用户名:密码存储在凭据插件中。这是一个定期更新密码的服务用户。 我正在寻找一种运行脚本的方法,最好是 Powershell,它将更新
我想知道如何创建 Jenkins 和 Jenkins 中运行的作业可以使用的凭据以连接到 3rd 方服务。 最佳答案 您应该指定您将使用的第 3 方服务。 以下是带有 的凭据示例bitbucket 我
我正在一个网站上工作,我们希望使用 Spring Security Kerberos 使用 Kerberos 身份验证。所以,我们不支持 NTLM。当用户发出未经身份验证的请求时,服务器将回复带有 h
如果我设置 git config --global credential.username my_username 选项,然后使用 --local 选项覆盖一个存储库,这并没有什么区别 - 它在尝试提
我正在尝试使用需要 gce_client_id 和 gce_client_secret key 的第 3 方应用程序。为了生成它们,我浏览了凭据图标并尝试创建一个 OAuth 2.0 客户端 ID。但
我在使用 Azure 时遇到身份验证问题。我有一个运行 powershell 脚本的连续构建服务器,我收到如下消息: Your Azure credentials have not been set
首先,我想说我在安全和身份验证方面的知识非常有限。 我有一个应用程序可以从 docker store 中提取和运行容器。这是一个私有(private)仓库,所以我需要传递用户名和密码,以便用户可以拉取
我使用 Google 文档中的代码(如下所示)来管理 Google 日历。 public class CalendarQuickstart { private static final Str
我是一名优秀的程序员,十分优秀!