简体   繁体   English

@AuthenticationPrincipal返回空用户

[英]@AuthenticationPrincipal return empty User

I have this controller where I save the post information associated with the currently authenticated user: 我有一个控制器,用于保存与当前经过身份验证的用户相关联的帖子信息:

@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 definition is here: @CurrentUser定义在这里:

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

When the controller is executed the user obtained by @AuthenticationPrincipal is empty and the one obtained by SecurityContextHolder contains all the information: 当执行控制器时,通过@AuthenticationPrincipal获得的用户为空,而通过SecurityContextHolder获得的用户包含所有信息:

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=sss4esob@gmail.com, enabled=true, fullName=Sergio Sánchez Sánchez, posts=[]}

As I understand using @EnableWebSecurity already enable in the context the resolver argument for the @AuthenticationPrincipal 据我了解,使用@EnableWebSecurity已经在上下文中启用了@AuthenticationPrincipal的resolver参数。

My Spring Security Configuration is this: 我的Spring Security配置是这样的:

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);
    }
}

I am using Spring Security 4.2.0.RELEASE 我正在使用Spring Security 4.2.0.RELEASE

thanks :) 谢谢 :)

This issue is because DelegatingFlashMessagesConfiguration from CustomFlashMessagesConfigurer eagerly initializes the handlerExceptionResolver which prevents the AuthenticationPrincipalArgumentResolver from being registered until after Spring MVC has constructed the DispatcherServlets custom argument resolvers. 这是因为从CustomFlashMessagesConfigurer DelegatingFlashMessagesConfiguration CustomFlashMessagesConfigurer急切地初始化handlerExceptionResolver,这将阻止AuthenticationPrincipalArgumentResolver的注册,直到Spring MVC构建了DispatcherServlets自定义参数解析器。

Therefore I have changed: 因此我改变了:

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

For this another: 为此:

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

This solves the problem. 这样就解决了问题。

The error message is quite clear. 错误消息很清楚。 Your CustomerUserDetails object sounds to be an entity object. 您的CustomerUserDetails对象听起来像是一个实体对象。 Add a default constructor in it: 在其中添加默认构造函数:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 AuthenticationPrincipal 返回空的 UserDetails object - AuthenticationPrincipal returns empty UserDetails object Spring Security 4 @AuthenticationPrincipal 为空,core.annotation.AuthenticationPrincipal 但不是 web.bind.annotation.AuthenticationPrincipal - Spring Security 4 @AuthenticationPrincipal empty with core.annotation.AuthenticationPrincipal but not web.bind.annotation.AuthenticationPrincipal ReactiveSecurityContextHolder.getContext() 为空,但 @AuthenticationPrincipal 有效 - ReactiveSecurityContextHolder.getContext() is empty but @AuthenticationPrincipal works 使用 @AuthenticationPrincipal 和 JwtAuthenticationToken 来使用自己的用户类 - Use @AuthenticationPrincipal with JwtAuthenticationToken to use own user class @AuthenticationPrincipal没有显示经过身份验证的用户 - @AuthenticationPrincipal doesn't show the authenticated user 当发送登录请求时,@AuthenticationPrincipal 的用户为空 - When send login request user be null for @AuthenticationPrincipal 为什么@AuthenticationPrincipal返回Authentication而不是主体对象? - Why does @AuthenticationPrincipal return the Authentication instead of the principal object? 如果几个用户输入为空,SQL搜索返回 - SQL search to return if several user inputs are empty @AuthenticationPrincipal UserModel 用户始终为 Null。 我尝试了很多解决方法 - @AuthenticationPrincipal UserModel user is always Null. I tried many solution methods @AuthenticationPrincipal 注释的重点是什么? - What is the point of @AuthenticationPrincipal annotation?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM