title: Spring-security context setup for 2-legged (client credentials) OAuth2 server
body: <p>What's the minimal setup for spring-security OAuth2 if I want to secure a REST server for one client? I don't want to use any unnecessary setup or implement any unnecessary beans. Maybe there's an "easy" tutorial / example out there already for spring-security + OAuth2? (Though I'm trying to avoid being too hopeful about that) </p>
  
  <p>My current working setup (working with the copy+past+wtf from the sparklr context) feels like too much:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;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"&gt;
  
      &lt;oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices"&gt;
          &lt;oauth:client-credentials /&gt;
      &lt;/oauth:authorization-server&gt;
  
      &lt;sec:authentication-manager alias="clientAuthenticationManager"&gt;
          &lt;sec:authentication-provider user-service-ref="clientDetailsUserService" /&gt;
      &lt;/sec:authentication-manager&gt;
  
      &lt;http pattern="/oauth/token" create-session="stateless"
              authentication-manager-ref="clientAuthenticationManager"
              xmlns="http://www.springframework.org/schema/security"&gt;
          &lt;intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" /&gt;
          &lt;anonymous enabled="false" /&gt;
          &lt;http-basic entry-point-ref="clientAuthenticationEntryPoint" /&gt;
  
          &lt;!-- include this only if you need to authenticate clients via request parameters --&gt;
          &lt;custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" /&gt;
          &lt;access-denied-handler ref="oauthAccessDeniedHandler" /&gt;
      &lt;/http&gt;
  
      &lt;oauth:resource-server id="resourceServerFilter"
              resource-id="rest_server" token-services-ref="tokenServices" /&gt;
  
      &lt;oauth:client-details-service id="clientDetails"&gt;
          &lt;oauth:client client-id="the_client" authorized-grant-types="client_credentials" 
                  authorities="ROLE_RESTREAD" secret="1234567890" /&gt;
      &lt;/oauth:client-details-service&gt;
  
  
      &lt;http pattern="/**" create-session="never"
              entry-point-ref="oauthAuthenticationEntryPoint"
              access-decision-manager-ref="accessDecisionManager"
              xmlns="http://www.springframework.org/schema/security"&gt;
          &lt;anonymous enabled="false" /&gt;
  
          &lt;intercept-url pattern="/rest/**" access="ROLE_RESTREAD" method="GET" /&gt;
          &lt;custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" /&gt;
          &lt;access-denied-handler ref="oauthAccessDeniedHandler" /&gt;
      &lt;/http&gt;
  
      &lt;bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" /&gt;
  
      &lt;bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices"&gt;
          &lt;property name="tokenStore" ref="tokenStore" /&gt;
          &lt;property name="supportRefreshToken" value="false" /&gt;
          &lt;property name="clientDetailsService" ref="clientDetails" /&gt;
          &lt;property name="accessTokenValiditySeconds" value="400000" /&gt;
          &lt;property name="refreshTokenValiditySeconds" value="0" /&gt;
      &lt;/bean&gt;
  
      &lt;bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"
              xmlns="http://www.springframework.org/schema/beans"&gt;
          &lt;constructor-arg&gt;
              &lt;list&gt;
                  &lt;bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" /&gt;
                  &lt;bean class="org.springframework.security.access.vote.RoleVoter" /&gt;
                  &lt;bean class="org.springframework.security.access.vote.AuthenticatedVoter" /&gt;
              &lt;/list&gt;
          &lt;/constructor-arg&gt;
      &lt;/bean&gt;
  
  
      &lt;bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"&gt;
          &lt;property name="realmName" value="theRealm" /&gt;
      &lt;/bean&gt;
  
      &lt;bean id="clientAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"&gt;
          &lt;property name="realmName" value="theRealm/client" /&gt;
          &lt;property name="typeName" value="Basic" /&gt;
      &lt;/bean&gt;
  
      &lt;bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter"&gt;
          &lt;property name="authenticationManager" ref="clientAuthenticationManager" /&gt;
      &lt;/bean&gt;
  
  
      &lt;bean id="clientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService"&gt;
          &lt;constructor-arg ref="clientDetails" /&gt;
      &lt;/bean&gt;
  
      &lt;bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" /&gt;
  
  
      &lt;sec:global-method-security pre-post-annotations="enabled" proxy-target-class="true"&gt;
          &lt;sec:expression-handler ref="oauthExpressionHandler" /&gt;
      &lt;/sec:global-method-security&gt;
  
      &lt;oauth:expression-handler id="oauthExpressionHandler" /&gt;
  
      &lt;oauth:web-expression-handler id="oauthWebExpressionHandler" /&gt;
  &lt;/beans&gt;   
  </code></pre>
  
  <p>I already have implemented the authenticationManager (UserDetailsService) as a part of implementing basic spring-security so that accounts and roles are persisted against our database.</p>
  
  <hr>
  
  <p>The beans I don't really get are:</p>
  
  <p><strong>userApprovalHandler</strong>: Why would I need any user approval in a client_credentials flow / grant? It seems, sparklr overrides the default <code>TokenServicesUserApprovalHandler</code> to auto-approve one client. Do I need to do that as well for the communication between my trusted client(s) and the server?</p>
  
  <p><strong>oauthAuthenticationEntryPoint</strong>: all sparklr does about this is:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"&gt;
      &lt;property name="realmName" value="sparklr2" /&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>What's that supposed to do?</p>
  
  <p><strong>clientCredentialsTokenEndpointFilter</strong>
  It says, I should include this only if I want to authenticate via request parameters.. So what I have in mind is exactly that: Send a GET(?) request to my server with the secret and get a token and with that token access the resources? So I'm thinking, the request for the token should contain the secret as request parameter..?</p>
  
  <p><strong>resourceServerFilter</strong>
  It seems to me that this indicates a separate resource server? How does that apply if my resources are on the same server as the authentication provider? </p>
  
  <p><strong>accessDecisionManager</strong>
  I don't remember having to use this when setting up my custom spring-security implementation, why would I want to do so now?</p>
  
  <p>Thanks for reading through! Hope someone can answer a few of my questions..</p>
  
  <h2>Update</h2>
  
  <p>I've updated the setup to the current working state. I can now request an access token with the client credentials:</p>
  
  <pre><code>$ curl -X -v -d 'client_id=the_client&amp;client_secret=secret&amp;grant_type=client_credentials' -X POST "http://localhost:9090/our-server/oauth/token"
  </code></pre>
  
  <p>and use that token to access protected resources:</p>
  
  <pre><code>$ curl -H "Authorization: Bearer fdashuds-5432fsd5-sdt5s5d-sd5" "http://localhost:9090/our-server/rest/social/content/posts"
  </code></pre>
  
  <p>It still feels like a lot of setup and my questions remain. Also I'm wondering if this is the right way to go for securing the communication between trusted client and REST server in general. </p>
  
  <p>It also still feels like the initial request for the token is not secure except if done via https, but will that suffice? </p>
  
  <p>Also what about the token itself, should I give it a long lifetime and persist it on the client? that would in any case mean catching a token expiration exception and then requesting a new one. Or should I do the handshake for every request? What about refreshing the token? I think I read somewhere that refresh token is not secure for the client credentials grant type..? Is it necessary to send the token as HTTP header or can I change that? I don't want to use the spring-security client stack for our client as it has a rather legacy setup (jboss 5) and all we did so far was integrate REST communication capabilities with request parameters..</p>
  
  <p>It would also help to know more about all the spring-security setup but the documentation is quite thin..</p>
  
  <h2>EDIT</h2>
  
  <p>Updated the spring security configuration to our current state. Also, here's our web.xml:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;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"&gt;
  
      &lt;display-name&gt;the-display-name&lt;/display-name&gt;
  
      &lt;context-param&gt;
          &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
          &lt;param-value&gt;/WEB-INF/spring-context.xml&lt;/param-value&gt;
      &lt;/context-param&gt;
  
      &lt;listener&gt;
          &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
      &lt;/listener&gt;
  
      &lt;listener&gt;
          &lt;listener-class&gt;org.springframework.web.context.request.RequestContextListener&lt;/listener-class&gt;
      &lt;/listener&gt;
  
      &lt;servlet&gt;
          &lt;servlet-name&gt;jersey-serlvet&lt;/servlet-name&gt;     
          &lt;servlet-class&gt;
              com.sun.jersey.spi.spring.container.servlet.SpringServlet
          &lt;/servlet-class&gt;        
          &lt;init-param&gt;
              &lt;param-name&gt;com.sun.jersey.config.property.packages&lt;/param-name&gt;
              &lt;param-value&gt;base.package.rest&lt;/param-value&gt;
          &lt;/init-param&gt;               
          &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
      &lt;/servlet&gt;
  
      &lt;servlet-mapping&gt;
          &lt;servlet-name&gt;jersey-serlvet&lt;/servlet-name&gt;
          &lt;url-pattern&gt;/rest/*&lt;/url-pattern&gt;
      &lt;/servlet-mapping&gt;
  
      &lt;servlet&gt;
          &lt;servlet-name&gt;appServlet&lt;/servlet-name&gt;
          &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;
          &lt;init-param&gt;
              &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
              &lt;param-value&gt;
              /WEB-INF/servlet-context.xml            
              &lt;/param-value&gt;
          &lt;/init-param&gt;
          &lt;load-on-startup&gt;2&lt;/load-on-startup&gt;
      &lt;/servlet&gt;
      &lt;servlet-mapping&gt;
          &lt;servlet-name&gt;appServlet&lt;/servlet-name&gt;
          &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
      &lt;/servlet-mapping&gt;
  
      &lt;filter&gt;
          &lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt;
          &lt;filter-class&gt;org.springframework.web.filter.DelegatingFilterProxy&lt;/filter-class&gt;
          &lt;init-param&gt;
              &lt;param-name&gt;contextAttribute&lt;/param-name&gt;
              &lt;param-value&gt;org.springframework.web.servlet.FrameworkServlet.CONTEXT.appServlet&lt;/param-value&gt;
          &lt;/init-param&gt;
      &lt;/filter&gt;
  
      &lt;filter-mapping&gt;
          &lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt;
          &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
      &lt;/filter-mapping&gt;
  
  &lt;/web-app&gt;
  </code></pre>
  
  <p>Note: The spring-security-context.xml from above will get initialized by the servlet-context. The spring-context.xml itself only initializes the beans. 
  (Also: Our Server also has a few views so all rest resources run under /rest hence the url-pattern. But: It is always necessary to have a separate servlet and spring context.)</p>