IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Spring Java Discussion :

Probleme de paramètres à la création


Sujet :

Spring Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté Avatar de petitpasdelune
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    221
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2006
    Messages : 221
    Par défaut Probleme de paramètres à la création
    Bonjour.
    Contexte : webapp Struts2+Spring2+Acegi / Tomcat 6.0.10 / windows XP
    Problème : J'ai une erreur lors de la création d'un bean. Spring me dit que la classe qu'il essaye d'instancier n'implémente pas l'interface voulue. Or cette classe l'implémente.
    Eléments :
    securityContext.xml
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
    <beans default-autowire="autodetect">
    ...
    	<bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
    		<constructor-arg value="/index.action"/>
    		<constructor-arg>
    			<list>
    				<ref bean="rememberMeServices"/>
    				<bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
    			</list>
    		</constructor-arg>
    		<property name="filterProcessesUrl" value="/j_acegi_logout"/>
    	</bean>
    	<bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
    		<property name="userDetailsService">
    			<ref bean="userDetailsService"/>
    		</property>
    		<property name="tokenValiditySeconds">
    			<value>2592000</value>
    		</property>
    		<property name="key">
    			<value>totoestuncon</value>
    		</property>
    		<property name="alwaysRemember">
    			<value>false</value>
    		</property>
    	</bean>
    ...
    </beans>
    Erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'org.acegisecurity.ui.logout.SecurityContextLogoutHandler#d5c0f9' with merged definition [Root bean: class [org.acegisecurity.ui.logout.SecurityContextLogoutHandler]; scope=singleton; abstract=false; lazyInit=false; autowireCandidate=true; autowireMode=4; dependencyCheck=0; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in ServletContext resource [/WEB-INF/securityContext.xml]]
    [main] DEBUG org.springframework.beans.CachedIntrospectionResults - Getting BeanInfo for class [org.acegisecurity.ui.logout.SecurityContextLogoutHandler]
    [main] DEBUG org.springframework.beans.CachedIntrospectionResults - Caching PropertyDescriptors for class [org.acegisecurity.ui.logout.SecurityContextLogoutHandler]
    [main] DEBUG org.springframework.beans.CachedIntrospectionResults - Found bean property 'class' of type [java.lang.Class]
    [main] DEBUG org.springframework.beans.CachedIntrospectionResults - Found bean property 'invalidateHttpSession' of type [boolean]
    [main] DEBUG org.springframework.core.CollectionFactory - Creating [java.util.LinkedHashMap]
    [main] DEBUG org.springframework.core.CollectionFactory - Creating [java.util.LinkedHashSet]
    [main] DEBUG org.springframework.core.CollectionFactory - Creating [java.util.LinkedHashMap]
    [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Ignoring constructor [public org.acegisecurity.ui.logout.LogoutFilter(java.lang.String,org.acegisecurity.ui.logout.LogoutHandler[])] of bean 'logoutFilter': org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'logoutFilter' defined in ServletContext resource [/WEB-INF/securityContext.xml]: Unsatisfied dependency expressed through constructor argument with index 1 of type [org.acegisecurity.ui.logout.LogoutHandler[]]: There are 0 beans of type [[Lorg.acegisecurity.ui.logout.LogoutHandler;] available for autowiring: []. There should have been exactly 1 to be able to autowire constructor of bean 'logoutFilter'.
    [main] INFO  org.springframework.beans.factory.support.DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1701bdc: defining beans [captchaEngine,captchaService,acegiDataSource,filterChainProxy,logoutFilter,secureChannelProcessor,insecureChannelProcessor,channelDecisionManager,channelProcessingFilter,filterInvocationInterceptor,httpSessionContextIntegrationFilter,rememberMeProcessingFilter,rememberMeServices,authenticationManager,authenticationProvider,userDetailsService,roleVoter,rememberMeAutheticationProvider,accessDecisionManager,authenticationProcessingFilter]; root of factory hierarchy
    [main] ERROR org.springframework.web.context.ContextLoader - Context initialization failed
    org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'logoutFilter' defined in ServletContext resource [/WEB-INF/securityContext.xml]: Unsatisfied dependency expressed through constructor argument with index 1 of type [org.acegisecurity.ui.logout.LogoutHandler[]]: There are 0 beans of type [[Lorg.acegisecurity.ui.logout.LogoutHandler;] available for autowiring: []. There should have been exactly 1 to be able to autowire constructor of bean 'logoutFilter'.
    	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:458)
    	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:140)
    ...
    Cette erreur est répétée 3x.

    Or, les classes org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices et org.acegisecurity.ui.logout.SecurityContextLogoutHandler implémentent l'interface org.acegisecurity.ui.logout.LogoutHandler.

    Si je commente le bean logoutFilter, tout fonctionne correctement.

    Avez-vous une idée de l'origine du problème.

    Merci.

    PPDL

  2. #2
    Membre Expert Avatar de willoi
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    1 355
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 355
    Par défaut
    Oui c'est bizarre effectivement fais voir ta classe TokenBasedRememberMeServices

  3. #3
    Membre expérimenté Avatar de petitpasdelune
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    221
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2006
    Messages : 221
    Par défaut
    (le problème reste le même si je supprime le bean rememberMeServices).

    La voilà :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
     
    public class TokenBasedRememberMeServices implements RememberMeServices, InitializingBean, LogoutHandler {
        //~ Static fields/initializers =====================================================================================
     
        public static final String ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY = "ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE";
        public static final String DEFAULT_PARAMETER = "_acegi_security_remember_me";
        protected static final Log logger = LogFactory.getLog(TokenBasedRememberMeServices.class);
     
        //~ Instance fields ================================================================================================
     
        private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl();
        private String key;
        private String parameter = DEFAULT_PARAMETER;
        private UserDetailsService userDetailsService;
        private long tokenValiditySeconds = 1209600; // 14 days
        private boolean alwaysRemember = false;
     
        //~ Methods ========================================================================================================
     
        public void afterPropertiesSet() throws Exception {
            Assert.hasLength(key);
            Assert.hasLength(parameter);
            Assert.notNull(userDetailsService);
        }
     
        public Authentication autoLogin(HttpServletRequest request, HttpServletResponse response) {
            Cookie[] cookies = request.getCookies();
     
            if ((cookies == null) || (cookies.length == 0)) {
                return null;
            }
     
            for (int i = 0; i < cookies.length; i++) {
                if (ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY.equals(cookies[i].getName())) {
                    String cookieValue = cookies[i].getValue();
     
                    if (Base64.isArrayByteBase64(cookieValue.getBytes())) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("Remember-me cookie detected");
                        }
     
                        // Decode token from Base64
                        // format of token is:  
                        //     username + ":" + expiryTime + ":" + Md5Hex(username + ":" + expiryTime + ":" + password + ":" + key)
                        String cookieAsPlainText = new String(Base64.decodeBase64(cookieValue.getBytes()));
                        String[] cookieTokens = StringUtils.delimitedListToStringArray(cookieAsPlainText, ":");
     
                        if (cookieTokens.length == 3) {
                            long tokenExpiryTime;
     
                            try {
                                tokenExpiryTime = new Long(cookieTokens[1]).longValue();
                            } catch (NumberFormatException nfe) {
                                cancelCookie(request, response,
                                    "Cookie token[1] did not contain a valid number (contained '" + cookieTokens[1] + "')");
     
                                return null;
                            }
     
                            // Check it has not expired
                            if (tokenExpiryTime < System.currentTimeMillis()) {
                                cancelCookie(request, response,
                                    "Cookie token[1] has expired (expired on '" + new Date(tokenExpiryTime)
                                    + "'; current time is '" + new Date() + "')");
     
                                return null;
                            }
     
                            // Check the user exists
                            // Defer lookup until after expiry time checked, to possibly avoid expensive lookup
                            UserDetails userDetails;
     
                            try {
                                userDetails = this.userDetailsService.loadUserByUsername(cookieTokens[0]);
                            } catch (UsernameNotFoundException notFound) {
                                cancelCookie(request, response,
                                    "Cookie token[0] contained username '" + cookieTokens[0] + "' but was not found");
     
                                return null;
                            }
     
                            // Immediately reject if the user is not allowed to login
                            if (!userDetails.isAccountNonExpired() || !userDetails.isCredentialsNonExpired()
                                || !userDetails.isEnabled()) {
                                cancelCookie(request, response,
                                    "Cookie token[0] contained username '" + cookieTokens[0]
                                    + "' but account has expired, credentials have expired, or user is disabled");
     
                                return null;
                            }
     
                            // Check signature of token matches remaining details
                            // Must do this after user lookup, as we need the DAO-derived password
                            // If efficiency was a major issue, just add in a UserCache implementation,
                            // but recall this method is usually only called one per HttpSession
                            // (as if the token is valid, it will cause SecurityContextHolder population, whilst
                            // if invalid, will cause the cookie to be cancelled)
                            String expectedTokenSignature = DigestUtils.md5Hex(userDetails.getUsername() + ":"
                                    + tokenExpiryTime + ":" + userDetails.getPassword() + ":" + this.key);
     
                            if (!expectedTokenSignature.equals(cookieTokens[2])) {
                                cancelCookie(request, response,
                                    "Cookie token[2] contained signature '" + cookieTokens[2] + "' but expected '"
                                    + expectedTokenSignature + "'");
     
                                return null;
                            }
     
                            // By this stage we have a valid token
                            if (logger.isDebugEnabled()) {
                                logger.debug("Remember-me cookie accepted");
                            }
     
                            RememberMeAuthenticationToken auth = new RememberMeAuthenticationToken(this.key, userDetails,
                                    userDetails.getAuthorities());
                            auth.setDetails(authenticationDetailsSource.buildDetails((HttpServletRequest) request));
     
                            return auth;
                        } else {
                            cancelCookie(request, response,
                                "Cookie token did not contain 3 tokens; decoded value was '" + cookieAsPlainText + "'");
     
                            return null;
                        }
                    } else {
                        cancelCookie(request, response,
                            "Cookie token was not Base64 encoded; value was '" + cookieValue + "'");
     
                        return null;
                    }
                }
            }
     
            return null;
        }
     
        private void cancelCookie(HttpServletRequest request, HttpServletResponse response, String reasonForLog) {
            if ((reasonForLog != null) && logger.isDebugEnabled()) {
                logger.debug("Cancelling cookie for reason: " + reasonForLog);
            }
     
            response.addCookie(makeCancelCookie(request));
        }
     
        public String getKey() {
            return key;
        }
     
        public String getParameter() {
            return parameter;
        }
     
        public long getTokenValiditySeconds() {
            return tokenValiditySeconds;
        }
     
        public UserDetailsService getUserDetailsService() {
            return userDetailsService;
        }
     
        public void loginFail(HttpServletRequest request, HttpServletResponse response) {
            cancelCookie(request, response, "Interactive authentication attempt was unsuccessful");
        }
     
        protected boolean rememberMeRequested(HttpServletRequest request, String parameter) {
        	if (alwaysRemember) {
        		return true;
        	}
     
        	return RequestUtils.getBooleanParameter(request, parameter, false);
        }
     
        public void loginSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication successfulAuthentication) {
            // Exit if the principal hasn't asked to be remembered
            if (!rememberMeRequested(request, parameter)) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Did not send remember-me cookie (principal did not set parameter '" + this.parameter
                        + "')");
                }
     
                return;
            }
     
            // Determine username and password, ensuring empty strings
            Assert.notNull(successfulAuthentication.getPrincipal());
            Assert.notNull(successfulAuthentication.getCredentials());
     
            String username;
            String password;
     
            if (successfulAuthentication.getPrincipal() instanceof UserDetails) {
                username = ((UserDetails) successfulAuthentication.getPrincipal()).getUsername();
                password = ((UserDetails) successfulAuthentication.getPrincipal()).getPassword();
            } else {
                username = successfulAuthentication.getPrincipal().toString();
                password = successfulAuthentication.getCredentials().toString();
            }
     
            Assert.hasLength(username);
            Assert.hasLength(password);
     
            long expiryTime = System.currentTimeMillis() + (tokenValiditySeconds * 1000);
     
            // construct token to put in cookie; format is:
            //     username + ":" + expiryTime + ":" + Md5Hex(username + ":" + expiryTime + ":" + password + ":" + key)
            String signatureValue = new String(DigestUtils.md5Hex(username + ":" + expiryTime + ":" + password + ":" + key));
            String tokenValue = username + ":" + expiryTime + ":" + signatureValue;
            String tokenValueBase64 = new String(Base64.encodeBase64(tokenValue.getBytes()));
            response.addCookie(makeValidCookie(expiryTime, tokenValueBase64, request));
     
            if (logger.isDebugEnabled()) {
                logger.debug("Added remember-me cookie for user '" + username + "', expiry: '" + new Date(expiryTime) + "'");
            }
        }
     
        public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
            cancelCookie(request, response, "Logout of user " + authentication.getName());
        }
     
        protected Cookie makeCancelCookie(HttpServletRequest request) {
            Cookie cookie = new Cookie(ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY, null);
            cookie.setMaxAge(0);
            cookie.setPath(StringUtils.hasLength(request.getContextPath()) ? request.getContextPath() : "/");
     
            return cookie;
        }
     
        protected Cookie makeValidCookie(long expiryTime, String tokenValueBase64, HttpServletRequest request) {
            Cookie cookie = new Cookie(ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY, tokenValueBase64);
            cookie.setMaxAge(60 * 60 * 24 * 365 * 5); // 5 years
            cookie.setPath(StringUtils.hasLength(request.getContextPath()) ? request.getContextPath() : "/");
     
            return cookie;
        }
     
        public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) {
            Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required");
            this.authenticationDetailsSource = authenticationDetailsSource;
        }
     
        public void setKey(String key) {
            this.key = key;
        }
     
        public void setParameter(String parameter) {
            this.parameter = parameter;
        }
     
        public void setTokenValiditySeconds(long tokenValiditySeconds) {
            this.tokenValiditySeconds = tokenValiditySeconds;
        }
     
        public void setUserDetailsService(UserDetailsService userDetailsService) {
            this.userDetailsService = userDetailsService;
        }
     
    	public boolean isAlwaysRemember() {
    		return alwaysRemember;
    	}
     
    	public void setAlwaysRemember(boolean alwaysRemember) {
    		this.alwaysRemember = alwaysRemember;
    	}
    }
    PPDL.

  4. #4
    Membre expérimenté Avatar de petitpasdelune
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    221
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2006
    Messages : 221
    Par défaut [up]
    Tout ce passe comme-ci Spring ne voyait pas que cette classe implémente
    l'interface.

    Je viens de vérifier et il n'y a pas de doublons dans le CLASSPATH.

    Voyez-vous autre chose ?

    PPDL.

  5. #5
    Membre éprouvé
    Inscrit en
    Juillet 2006
    Messages
    74
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Juillet 2006
    Messages : 74
    Par défaut
    as-tu déclarer le bean suivant :
    filterChainProxy

    qui te permet de lister les différents filtres que tu vas utiliser dans ton moteur spring. Exemple :

    <bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
    <property name="filterInvocationDefinitionSource">
    <value>
    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
    PATTERN_TYPE_APACHE_ANT
    /**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
    </value>
    </property>
    </bean>

  6. #6
    Membre expérimenté Avatar de petitpasdelune
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    221
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Avril 2006
    Messages : 221
    Par défaut
    Oui.
    Il existe et sa création est OK quand je supprime le bean fautif :
    (version sans logoutFilter)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    	<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
    	  <property name="filterInvocationDefinitionSource">
    	    <value>
    			CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
    			PATTERN_TYPE_APACHE_ANT
    			/j_acegi_security_check*=channelProcessingFilter,httpSessionContextIntegrationFilter,authenticationProcessingFilter
    			/*.action=channelProcessingFilter,httpSessionContextIntegrationFilter,rememberMeProcessingFilter,filterInvocationInterceptor
    	    </value>
    	  </property>
    	</bean>
    (version avec logoutFilter)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    	<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
    	  <property name="filterInvocationDefinitionSource">
    	    <value>
    			CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
    			PATTERN_TYPE_APACHE_ANT
    			/j_acegi_security_check*=channelProcessingFilter,httpSessionContextIntegrationFilter,authenticationProcessingFilter
    			/*.action=channelProcessingFilter,httpSessionContextIntegrationFilter,logoutFilter,rememberMeProcessingFilter,filterInvocationInterceptor
    	    </value>
    	  </property>
    	</bean>
    PPDL.

Discussions similaires

  1. deux probleme:vue 2d et création par clic
    Par info_amel dans le forum OpenGL
    Réponses: 9
    Dernier message: 20/05/2008, 13h04
  2. [CrystalReportViewerURL] Probleme de paramètre
    Par mikl_apo dans le forum SAP Crystal Reports
    Réponses: 0
    Dernier message: 07/02/2008, 11h33
  3. Probleme passage paramètres
    Par cali8401 dans le forum API standards et tierces
    Réponses: 1
    Dernier message: 22/03/2007, 22h21
  4. probleme lors de la création d'un utilisateur sur un poste client.
    Par passion_info dans le forum Windows Serveur
    Réponses: 5
    Dernier message: 29/11/2006, 11h13
  5. Fenêtre enfant MDI : passage paramètre à la création
    Par Orangina dans le forum C++Builder
    Réponses: 3
    Dernier message: 21/07/2004, 11h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo