Spring boot:获取当前用户的用户名

时间:2018-05-15 16:50:24

标签: java spring-boot spring-security

我试图使用Spring的安全性获取当前登录的用户名,但Principal对象返回null。

这是我的REST控制器方法:

@RequestMapping("/getCurrentUser")
public User getCurrentUser(Principal principal) {

    String username = principal.getName();
    User user = new User();
    if (null != username) {
        user = userService.findByUsername(username);
    }

    return user;
}

注意:我正在运行Spring boot 1.5.13和spring security 4.2.6

  • 这是我的安全配置类:

    @Configuration
    
    @EnableWebSecurity
    
    public class SecurityConfig extends WebSecurityConfigurerAdapter{
    
        @Autowired
        private Environment env;
    
        @Autowired
        private UserSecurityService userSecurityService;
    
        private BCryptPasswordEncoder passwordEncoder() {
            return SecurityUtility.passwordEncoder();
        }
    
        private static final String[] PUBLIC_MATCHERS = {
                "/css/**",
                "/js/**",
                "/image/**",
                "/book/**",
                "/user/**"
        };
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable().cors().disable().httpBasic().and().authorizeRequests()
            .antMatchers(PUBLIC_MATCHERS).permitAll().anyRequest().authenticated();
        }
    
        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(userSecurityService).passwordEncoder(passwordEncoder());
        }
    
        @Bean
        public HttpSessionStrategy httpSessionStrategy() {
            return new HeaderHttpSessionStrategy();
        }
    }
    
  • 这是我的用户安全服务类:

    @Service
    
    public class UserSecurityService implements UserDetailsService {
    
    private static final Logger LOG = LoggerFactory.getLogger(UserSecurityService.class);
    
        @Autowired 
        private UserRepository userRepository;
    
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            User user = userRepository.findByUsername(username);
            if(null == user) {
                LOG.warn("Username {} not found", username);
                throw new UsernameNotFoundException("Username "+username+" not found");
            }
            return user;
        }
    }
    
  • 这是我的用户类:

    @Entity
    
    public class User implements UserDetails, Serializable {
    
        private static final long serialVersionUID = 902783495L;
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Column(name="Id", nullable=false, updatable = false)
        private Long id;
    
        private String username;
        private String password;
        private String firstName;
        private String lastName;
    
        private String email;
        private String phone;
        private boolean enabled = true;
    
        @OneToMany(mappedBy = "user", cascade=CascadeType.ALL, fetch = FetchType.EAGER)
        @JsonIgnore
        private Set<UserRole> userRoles = new HashSet<>();
    }
    

5 个答案:

答案 0 :(得分:1)

假设您的User类实现UserDetails,您可以从User获取SecurityContextHolder而无需依赖注入。

public User getCurrentUser(Principal principal) {

  return ((User) SecurityContextHolder.getContext()
            .getAuthentication()
            .getPrincipal());
}

答案 1 :(得分:1)

之前的答案应该可行, 如果使用spring web MVC控制器,你也可以使用spring默认方法参数解析器(@RestController public class AcceptConnectionController { @PostMapping(value = "/") public void controllerMethod(@AuthenticationPrincipal final MyPrincipal user) { //... } }

将它自动注入你的控制器中。

控制器可以:

MyPrincipal

在上面的示例中,org.springframework.security.authentication.AbstractAuthenticationToken扩展了from kivy.app import App from kivy.lang import Builder from kivy.core.window import Window class Main(App): def build(self): base = Builder.load_file("main.kv") base.ids.img.width = Window.width base.ids.img.height = Window.height return base 然后,您可以将此主体传递给服务层。

答案 2 :(得分:0)

按照@cosmos的要求-您是否正在使用Spring Security?

如果是,则应执行以下操作:

在您的SecurityConfig中:

@Bean
public AuthenticationManager customAuthenticationManager() throws Exception {
    return authenticationManager();
}

在您的控制器中:

private String getPrincipal() {
        String userName = null;
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        if (principal instanceof UserDetails) {
            userName = ((UserDetails) principal).getUsername();
        } else {
            userName = principal.toString();
        }
        return userName;
    }

答案 3 :(得分:0)

有多种方法可以做到这一点。

使用SecurityContextHolder

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName();

使用控制器中的Principal

@RequestMapping(value = "/myusername", method = RequestMethod.GET)
@ResponseBody
public String currentUserName(Principal principal) {
    return principal.getName();
}

来自HttpServletRequest

@RequestMapping(value = "/myusername", method = RequestMethod.GET)
@ResponseBody
public String getUsername(HttpServletRequest req) {
    return req.getUserPrincipal.getName();
}

答案 4 :(得分:0)

这是一种用于获取用户主体的方法

@PutMapping(value = "/{userId}")
public ResponseEntity<?> updateUser(@Valid @RequestBody UserPutRequest updateRequest, @PathVariable String userId,
        Authentication authentication) {
    Optional<UserObject> userOptional = userRepository.findById(userId);
    UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
    UserObject currentUser = userRepository.findByEmail(userPrincipal.getEmail());
}