Printemps-contexte de sécurité de l'installation pour 2 pattes (informations d'identification du client) OAuth2 serveur
Quelle est la configuration minimale pour le printemps-sécurité OAuth2 si je tiens à assurer un REPOS serveur pour un client? Je ne veux pas utiliser inutilement de l'installation ou de mettre en œuvre tous les haricots. Peut-être il y a un "facile" tutorial /exemple il y en a déjà pour le printemps-sécurité + OAuth2? (Même si je suis en essayant d'éviter d'être trop optimiste à ce sujet)
Mon travail en cours d'installation (en collaboration avec la copie+passé+wtf de la sparklr contexte) se sent comme trop:
<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>
J'ai déjà mis en œuvre la authenticationManager (UserDetailsService) dans le cadre de la mise en œuvre de base de ressort de sécurité afin que les comptes et les rôles sont conservées à l'encontre de notre base de données.
Les haricots je n'ai pas vraiment à obtenir sont:
userApprovalHandler: Pourquoi aurais-je besoin de l'approbation de l'utilisateur dans un client_credentials de débit /de la subvention? Il semble, sparklr remplace la valeur par défaut TokenServicesUserApprovalHandler
à l'auto-approuver un client. Ai-je besoin d'en faire autant pour la communication entre mon client de confiance(s) et le serveur?
oauthAuthenticationEntryPoint: tous les sparklr ne à ce sujet est:
<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="sparklr2" />
</bean>
Ce que ça à faire?
clientCredentialsTokenEndpointFilter
Cela dit, je devrais inclure ce que si je veux de s'authentifier via les paramètres de la demande.. Donc ce que j'ai à l'esprit, c'est exactement cela: Envoyer un GET(?) demande à mon serveur avec le secret et obtenir un jeton et avec le jeton d'accès aux ressources? Donc, je pense, la demande pour le jeton doit contenir le secret en tant que paramètre de la requête..?
resourceServerFilter
Il me semble que cela indique une ressource séparée serveur? Comment cela s'applique si mes ressources sont sur le même serveur que le fournisseur d'authentification?
accessDecisionManager
Je ne me souviens pas avoir à utiliser lors de la configuration de mon personnalisée printemps-implémentation de la sécurité, pourquoi voudrais-je faire maintenant?
Merci pour la lecture par le biais de! J'espère que quelqu'un peut répondre à quelques une de mes questions..
Mise à jour
J'ai mis à jour la configuration de l'actuel état de fonctionnement. Je peux maintenant demander un jeton d'accès avec les informations d'identification du client:
$ curl -X -v -d 'client_id=the_client&client_secret=secret&grant_type=client_credentials' -X POST "http://localhost:9090/our-server/oauth/token"
et utiliser ce jeton d'accès à des ressources protégées:
$ curl -H "Authorization: Bearer fdashuds-5432fsd5-sdt5s5d-sd5" "http://localhost:9090/our-server/rest/social/content/posts"
Il se sent encore comme beaucoup de paramètres et de mes questions restent en suspens. Aussi, je me demande si c'est la bonne façon de faire pour sécuriser la communication entre des clients de confiance et de REPOS serveur en général.
Elle aussi se sent encore comme la demande initiale pour le jeton n'est pas bloqué, sauf si cela se fait via le protocole https, mais qui suffisent?
Aussi ce que sur le jeton lui-même, dois-je lui donner une longue durée de vie et persistent sur le client? que serait, en tout cas dire attraper un jeton d'expiration exception et puis demander un nouveau. Ou dois-je faire la poignée de main pour chaque requête? Ce propos de l'actualisation de l'jeton? Je pense que j'ai lu quelque part que le jeton d'actualisation n'est pas sécurisé pour les informations d'identification du client type de subvention..? Est-il nécessaire d'envoyer le jeton comme en-tête HTTP ou puis-je changer cela? Je ne veux pas utiliser le printemps-la clientèle de la sécurité de la pile pour notre client, car il est plutôt l'héritage de configuration (jboss 5) et l'ensemble nous avons fait jusqu'à présent était de REPOS intégrer des capacités de communication avec les paramètres de la demande..
Il serait également aider à en savoir plus à propos de tous les printemps-configuration de la sécurité, mais la documentation est assez mince..
MODIFIER
Mis à jour le printemps de configuration de la sécurité de notre état actuel. Aussi, voici notre 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>
Remarque: L'spring-security-context.xml d'en haut vous sont initialisées par le servlet-contexte. L'spring-context.xml lui-même, n'initialise les haricots.
(Aussi: Notre Serveur a aussi quelques points de vue donc, tout le reste des ressources exécuter sous /reste donc l'url-pattern. Mais: Il est toujours nécessaire d'avoir une servlet et le printemps contexte.)
- vous pouvez poster votre configuration de travail? Je suis aussi actuellement de la difficulté, de la fixation d'un simple api rest avec oauth2
- Salut Hendrik, mis à jour à ma question. Espérons que cela aide.
- Merci Pete pour la prestation de travail par exemple. J'ai eu du mal à trouver de travail exemple de printemps de sécurité avec client_credentials type de subvention. Ce post m'a beaucoup aidé.
Vous devez vous connecter pour publier un commentaire.
userApprovalHandler: si vous avez seulement un client dans votre système, je suis d'accord les utilisateurs ne devraient pas avoir à approuver accéder à leurs données.
oauthAuthenticationEntryPoint: Normalement, si l'authentification échoue, la réponse est de type JSON. La Documentation dit "Si l'authentification échoue et que l'appelant a demandé un type de contenu spécifique de la réponse, ce point d'entrée peut envoyer un, avec un standard de statut 401."
clientCredentialsTokenEndpointFilter: l'Émission d'un jeton d'accès est un processus en deux étapes. Tout d'abord, vous envoyer l'utilisateur vers le serveur de ressources pour s'authentifier. Cette redirection est authentifié par le client, idéalement avec les en-Têtes HTTP (+clé secrète). En retour, le client reçoit un code, qui peuvent être échangés pour un jeton.
Vous n'avez pas directement le commerce de la touche+secret pour un jeton, car il ne contient aucune approbation de la part de l'utilisateur.
resourceServerFilter: je pense le but de ce indique ce que les clients ont accès à quelles ressources, si vous avez de nombreuses ressources différentes.
accessDecisionManager: Pour OAuth2 vous avez besoin d'un ScopeVoter, de sorte que la valeur par défaut du Gestionnaire n'est pas assez bon.
Généralement:
Si vous n'avez qu'un seul client d'accéder aux ressources pour les utilisateurs, alors peut-être envisager l'utilisation de Digérer au lieu de OAuth2?
Et si vous souhaitez uniquement pour authentifier le client (l'utilisateur), puis OAuth2 est exagéré. L'authentification du Client dans OAuth2 est vraiment le même que l'Authentification de Base sur le protocole https.
Un bon exemple de oauth2 pour le REPOS des clients et des utilisateurs avec ressort de sécurité ouath 2.0:
http://www.e-zest.net/blog/rest-authentication-using-oauth-2-0-resource-owner-password-flow-protocol/