Spring boot: Получить имя пользователя текущего пользователя - PullRequest
0 голосов
/ 15 мая 2018

Я пытаюсь получить текущее имя пользователя в системе, используя безопасность Spring, но объект Principal возвращает ноль.

Это мой метод контроллера 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 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<>();
    }
    

Ответы [ 4 ]

0 голосов
/ 22 августа 2018

Есть несколько способов сделать это.

Использование 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();
}
0 голосов
/ 22 мая 2018

Предыдущий ответ должен работать нормально, если вы используете Spring Web MVC контроллеры, вы также можете вставлять его в свои контроллеры автоматически из коробки, используя средства разрешения аргументов метода по умолчанию (org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver)

Контроллер можетdo:

@RestController
public class AcceptConnectionController {

    @PostMapping(value = "/")
    public void controllerMethod(@AuthenticationPrincipal final MyPrincipal user) {
        //...
    }

}

В приведенном выше примере MyPrincipal extends org.springframework.security.authentication.AbstractAuthenticationToken Затем этот принципал можно передать на уровень обслуживания.

0 голосов
/ 27 июля 2018

Как спросил @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;
    }
0 голосов
/ 15 мая 2018

Предполагая, что класс User реализует UserDetails, вы можете получить User из SecurityContextHolder без внедрения зависимостей.

public User getCurrentUser(Principal principal) {

  return ((User) SecurityContextHolder.getContext()
            .getAuthentication()
            .getPrincipal());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...