2014-09-03 15 views
6

में उपयोगकर्ता नाम प्राप्त करें मैंने वर्कफ़्लो पर कार्रवाइयों को निष्पादित करने के लिए एक विश्वसनीय वेब सेवाएं बनाई हैं। वेब सेवा को अपने स्वयं के प्रमाणीकरण सर्वर के साथ oauth2 से सुरक्षित किया गया है। मैं अपने वर्कफ़्लो में जानकारी जोड़ना चाहता हूं कि किसने कार्रवाई की है। मैं यह नहीं समझ सकता कि वेब सेवा को कॉल करने वाले व्यक्ति का उपयोगकर्ता नाम कौन प्राप्त करें।स्प्रिंग सुरक्षा oauth2: REST webservice

वेब सेवा कार्यान्वयन के लिए मैं जर्सी (1.18.1) का उपयोग कर रहा हूं और सुरक्षा के लिए मैं वसंत-सुरक्षा-ओथ 2 (2.0.2.RELEASE) का उपयोग कर रहा हूं।

मैं डेटाबेस टोकन स्टोर का उपयोग कर रहा हूं और इसमें एक तालिका OAUTH_ACCESS_TOKEN (TOKEN_ID, टोकन, AUTHENTICATION_ID, USER_NAME, CLIENT_ID, प्रमाणीकरण, REFRESH_TOKEN) शामिल है जो सही जानकारी रखने जैसा दिखता है। इसमें उपयोगकर्ता का नाम और टोकन है लेकिन टोकन एक धारावाहिक जावा ऑब्जेक्ट की तरह दिखता है, इसलिए मैं इसे स्वयं से पूछ नहीं सकता।

वेब सेवा:

@Component 
@Path("/workflows") 
public class WorkflowRestService { 

    @POST 
    @Path("/{id}/actions") 
    @Produces(MediaType.APPLICATION_JSON) 
    @Transactional 
    public Response executeActions(@PathParam("id") String id, Map<String, Object> actionArgs) throws JAXBException, HealthDataException { 

     //would like to have/get username here. 

     Workflow workflow = workflowService.get(id); 
     Action action = actionFactory.getAction(actionArgs); 
     workflow.execute(action); 
     Workflow update = workflowService.update(workflow); 
     return Response.ok(update).build(); 
    } 
} 

वेब सेवा सुरक्षा config:

<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:oauth="http://www.springframework.org/schema/security/oauth2" 
     xmlns:sec="http://www.springframework.org/schema/security" 
     xsi:schemaLocation="http://www.springframework.org/schema/context 
     http://www.springframework.org/schema/context/spring-context-3.2.xsd 
     http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-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/security/oauth2 
     http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd"> 

    <context:property-placeholder location="classpath:main.properties"/> 

    <!-- Protected resources --> 
    <http authentication-manager-ref="" pattern="/workflows/**" 
      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="/workflows/**" 
         access="ROLE_USER"/> 
     <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="dstest"/> 
    </bean> 

    <bean id="oauthAccessDeniedHandler" 
      class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler"/> 

    <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 alias="authenticationManager" xmlns="http://www.springframework.org/schema/security"> 
     <authentication-provider> 
      <jdbc-user-service data-source-ref="securityDataSource"/> 
     </authentication-provider> 
    </authentication-manager> 

    <bean id="clientDetailsUserService" 
      class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService"> 
     <constructor-arg ref="clientDetails"/> 
    </bean> 

    <!-- Token Store --> 
    <bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore"> 
     <constructor-arg ref="securityDataSource" /> 
    </bean> 

    <bean id="oAuth2RequestFactory" class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory"> 
     <constructor-arg ref="clientDetails"/> 
    </bean> 

    <bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices"> 
     <property name="tokenStore" ref="tokenStore"/> 
     <property name="supportRefreshToken" value="true"/> 
     <property name="clientDetailsService" ref="clientDetails"/> 
     <!-- VIV --> 
     <property name="accessTokenValiditySeconds" value="10"/> 
    </bean> 

    <oauth:resource-server id="resourceServerFilter" 
          resource-id="dstest" 
          token-services-ref="tokenServices"/> 

    <!-- Client Definition --> 
    <oauth:client-details-service id="clientDetails"> 

     <oauth:client client-id="healthdata-client" 
         authorized-grant-types="password,authorization_code,refresh_token,implicit,redirect" 
         authorities="ROLE_CLIENT, ROLE_TRUSTED_CLIENT" 
         redirect-uri="/web" 
         scope="read,write,trust" 
         access-token-validity="300" 
         refresh-token-validity="6000"/> 

    </oauth:client-details-service> 


    <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> 

प्राधिकरण सर्वर config:

<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:oauth="http://www.springframework.org/schema/security/oauth2" 
     xmlns:sec="http://www.springframework.org/schema/security" 
     xsi:schemaLocation="http://www.springframework.org/schema/context 
     http://www.springframework.org/schema/context/spring-context-3.2.xsd 
     http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-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/security/oauth2 
     http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd"> 

    <context:property-placeholder location="classpath:main.properties"/> 

    <!-- Definition of the Authentication Service --> 
    <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" after="BASIC_AUTH_FILTER"/> 
     <access-denied-handler ref="oauthAccessDeniedHandler"/> 
    </http> 

    <!-- Protected resources --> 
    <http pattern="https://stackoverflow.com/users/**" 
      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="https://stackoverflow.com/users/**" 
         access="ROLE_USER"/> 
     <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="dstest"/> 
    </bean> 

    <bean id="clientAuthenticationEntryPoint" 
      class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint"> 
     <property name="realmName" value="dstest/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 in config file --> 
    <authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security"> 
     <authentication-provider user-service-ref="clientDetailsUserService"/> 
    </authentication-manager> 

    <authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security"> 
     <authentication-provider> 
      <jdbc-user-service data-source-ref="securityDataSource"/> 
     </authentication-provider> 
    </authentication-manager> 

    <bean id="clientDetailsUserService" 
      class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService"> 
     <constructor-arg ref="clientDetails"/> 
    </bean> 

    <!-- Token Store --> 
    <bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore"> 
     <constructor-arg ref="securityDataSource" /> 
    </bean> 

    <bean id="oAuth2RequestFactory" class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory"> 
     <constructor-arg ref="clientDetails"/> 
    </bean> 

    <bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices"> 
     <property name="tokenStore" ref="tokenStore"/> 
     <property name="supportRefreshToken" value="true"/> 
     <property name="clientDetailsService" ref="clientDetails"/> 
     <!-- VIV --> 
     <property name="accessTokenValiditySeconds" value="10"/> 
    </bean> 

    <bean id="userApprovalHandler" 
      class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler"> 
     <property name="tokenStore" ref="tokenStore"/> 
     <property name="requestFactory" ref="oAuth2RequestFactory"/> 
    </bean> 

    <!-- Token management --> 
    <oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices" 
           user-approval-handler-ref="userApprovalHandler" token-endpoint-url="/oauth/token"> 
     <oauth:authorization-code/> 
     <oauth:implicit/> 
     <oauth:refresh-token/> 
     <oauth:client-credentials/> 
     <oauth:password/> 
    </oauth:authorization-server> 

    <oauth:resource-server id="resourceServerFilter" 
          resource-id="dstest" 
          token-services-ref="tokenServices"/> 

    <!-- Client Definition --> 
    <oauth:client-details-service id="clientDetails"> 

     <oauth:client client-id="healthdata-client" 
         authorized-grant-types="password,authorization_code,refresh_token,implicit,redirect" 
         authorities="ROLE_CLIENT, ROLE_TRUSTED_CLIENT" 
         redirect-uri="/web" 
         scope="read,write,trust" 
         access-token-validity="300" 
         refresh-token-validity="6000"/> 

    </oauth:client-details-service> 


    <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> 

उत्तर

16

आप प्रमाणीकरण के लिए स्प्रिंग सुरक्षा का उपयोग कर रहे के बाद से मुझे लगता है कि आप उम्मीद करेंगे SecurityContext तक पहुंचें (सामान्य थ्रेड स्थानीय एक्सेसर के माध्यम से):

Authentication authentication = SecurityContextHolder.getContext() 
    .getAuthentication(); 

या HttpServletRequest के माध्यम से:

Principal principal = request.getUserPrincipal(); 

(या यदि आप वसंत MVC उपयोग कर रहे थे सिर्फ अपने @Controller में एक विधि पैरामीटर के रूप में Principal जोड़ें)। किसी भी मामले में, चूंकि आप स्प्रिंग ओएथ फ़िल्टर के पीछे हैं, आपको यह भी पता होना चाहिए कि Principal/AuthenticationOAuth2Authentication का उदाहरण है और उपयोगकर्ता के विवरण के साथ-साथ ग्राहक भी वहां हैं।

+1

मुझे वास्तव में सुरक्षा कॉन्टेक्स्ट तक पहुंच है और इसलिए प्रिंसिपल प्राप्त हो सकता है। – Xymon

संबंधित मुद्दे