2016-12-08 2 views
0

J'ai ce contrôleur où j'enregistrer les informations post associé à l'utilisateur authentifié:@AuthenticationPrincipal retour vide Utilisateur

@PostMapping("/create") 
    public String processPost(
      @CurrentUser User activeUser, 
      @ModelAttribute @Valid Post post, 
      Errors errors){ 
     if(errors.hasErrors()){ 
      return "admin/post/create"; 
     } 
     User user2 = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 
     logger.info("Información del usuario mediate @CurrentUser: " + activeUser.toString()); 
     logger.info("Información del usuario mediate SecurityContextHolder: " + user2.toString()); 
     post.setAuthor(activeUser); 
     postService.create(post); 
     return "redirect:/admin/posts/all"; 
    } 

@CurrentUser définition est ici:

package services.security; 

import java.lang.annotation.Documented; 
import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 
import org.springframework.security.core.annotation.AuthenticationPrincipal; 

/** 
* 
* @author sergio 
*/ 
@Target({ElementType.PARAMETER, ElementType.TYPE}) 
@Retention(RetentionPolicy.RUNTIME) 
@Documented 
@AuthenticationPrincipal 
public @interface CurrentUser {} 

Lorsque le contrôleur est exécuté le l'utilisateur obtenu par @AuthenticationPrincipal est vide et celui obtenu par SecurityContextHolder contient toutes les informations:

2016-12-10 19:37:52 INFO PostController:62 - Información del usuario mediate @CurrentUser: User{id=null, username=null, passwordClear=null, confirmPassword=null, password=null, email=null, enabled=true, fullName=null, posts=[]} 
2016-12-10 19:37:52 INFO PostController:63 - Información del usuario mediate SecurityContextHolder: User{id=1, username=sergio11, passwordClear=null, confirmPassword=null, password=$2a$10$LJvYTNacIvqZWDQWjF7xaeheK1MrF.FkXxovb2QgcF2CMudA1mM/., [email protected], enabled=true, fullName=Sergio Sánchez Sánchez, posts=[]} 

Comme je comprends l'aide @EnableWebSecurity permettent déjà dans le contexte de l'argument résolveur pour la @AuthenticationPrincipal

Mon printemps Configuration de la sécurité est la suivante:

package config.security; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.ApplicationEventPublisher; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher; 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 
import org.springframework.security.core.userdetails.UserDetailsService; 
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 
import org.springframework.security.crypto.password.PasswordEncoder; 
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; 
import services.security.CustomUserDetailsService; 
/** 
* 
* @author sergio 
*/ 
@Configuration 
@EnableWebSecurity 
@ComponentScan(basePackageClasses = CustomUserDetailsService.class) 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private UserDetailsService userDetailsService; 
    @Autowired 
    private DefaultAuthenticationEventPublisher defaultAuthenticationEventPublisher; 

    @Bean 
    public PasswordEncoder passwordEncoder() { 
     PasswordEncoder encoder = new BCryptPasswordEncoder(); 
     return encoder; 
    } 

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth 
      .authenticationEventPublisher(defaultAuthenticationEventPublisher) 
      .userDetailsService(userDetailsService) 
      .passwordEncoder(passwordEncoder()); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.authorizeRequests() 
       .antMatchers("/admin/signup").anonymous() 
       .antMatchers("/admin/**").authenticated() 
       .anyRequest().permitAll() 
       .and() 
       .formLogin().loginPage("/admin/login").permitAll() 
       .usernameParameter("username").passwordParameter("password") 
       .and() 
       .logout() 
        .logoutRequestMatcher(new AntPathRequestMatcher("/admin/logout")) 
        .logoutSuccessUrl("/admin/login?logout") 
       .and() 
       .exceptionHandling().accessDeniedPage("/403") 
       .and() 
       .csrf(); 
    } 

    @Bean 
    public DefaultAuthenticationEventPublisher authenticationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { 
     return new DefaultAuthenticationEventPublisher(applicationEventPublisher); 
    } 
} 

J'utilise Spring Security 4.2.0.RELEASE

merci :)

Répondre

1

Ce problème est dû au fait DelegatingFlashMessagesConfiguration de CustomFlashMessagesConfigurer avec impatience la handlerExceptionResolver initialise qui empêche la AuthenticationPrincipalArgumentResolver d'être enregistré qu'après Spring MVC a construit l'argument sur mesure DispatcherServlets résolveurs.

donc j'ai changé:

@Configuration 
@EnableWebMvc 
@ComponentScan(value = { "controllers", "services", "listeners" }) 
@Import(value = { ThymeleafConfig.class, i18nConfig.class, CustomFlashMessagesConfigurer.class }) 
public class WebConfig extends WebMvcConfigurerAdapter 

Pour cette autre:

@Configuration 
@ComponentScan(value = { "controllers", "services", "listeners" }) 
@Import(value = { ThymeleafConfig.class, i18nConfig.class, CustomFlashMessagesConfigurer.class }) 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurerAdapter 

Cela résout le problème.

0

Les mes d'erreur La sauge est assez claire. Votre objet CustomerUserDetails semble être un objet entité. Ajoutez un constructeur par défaut il:

public class CustomUserDetails extends User implements UserDetails { 
//.. 
    public CustomUserDetails(){} 
//.. 
} 
+0

merci, j'ai déjà essayé et est apparu cette erreur: Échec de la validation pour les classes [services.security.CustomUserDetails] pendant le temps de persistance pour les groupes. En d'autres termes, la validation du bean JPA échoue. –

+0

Il semble que l'objet soit vide car toutes les validations échouent. –