J'ai créé un service Web RESTful pour exécuter des actions sur un flux de travail. Le service web est sécurisé avec oauth2 avec mon propre serveur d'autorisation. Je veux ajouter des informations à mon flux de travail sur qui a exécuté une action dessus. Ce que je ne peux pas comprendre, c'est qui obtenir le nom d'utilisateur de celui qui appelle le service Web.
Pour la mise en œuvre des services Web, j'utilise jersey (1.18.1) et pour la sécurité, j'utilise spring-security-oauth2 (2.0.2.RELEASE).
J'utilise un magasin de jetons de base de données et celui-ci contient une table OAUTH_ACCESS_TOKEN (TOKEN_ID, TOKEN, AUTHENTICATION_ID, USER_NAME, CLIENT_ID, AUTHENTICATION, REFRESH_TOKEN) qui semble contenir les informations correctes. Il a le nom d'utilisateur et le jeton, mais le jeton ressemble à un objet java sérialisé, je ne peux donc pas l'interroger moi-même.
Service Web:
@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();
}
}
Configuration de sécurité du service Web:
<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>
Configuration du serveur d'autorisation:
<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="/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="/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>
Puisque vous utilisez Spring Security pour l'authentification, je m'attends à ce que vous ayez accès à SecurityContext
(via l'accesseur local de thread habituel):
Authentication authentication = SecurityContextHolder.getContext()
.getAuthentication();
ou via HttpServletRequest
:
Principal principal = request.getUserPrincipal();
(ou si vous utilisiez Spring MVC, ajoutez simplement Principal
un paramètre de méthode dans votre @Controller
). Dans les deux cas, étant donné que vous êtes derrière un filtre Spring OAuth, vous devez également constater qu'il Principal/Authentication
s'agit d'une instance de OAuth2Authentication
et que les détails de l'utilisateur ainsi que le client s'y trouvent.
Cet article est collecté sur Internet, veuillez indiquer la source lors de la réimpression.
En cas d'infraction, veuillez [email protected] Supprimer.
laisse moi dire quelques mots