[英]Getting user information from the current session on Spring?
I have been trying to get user info from the current session to do some findByUsername like operations.我一直在尝试从当前的 session 获取用户信息,以执行一些类似 findByUsername 的操作。 I've tried @AuthenticationPrinciple but even though I fed it with my UserDetails implementation it just returns null.
我已经尝试过@AuthenticationPrinciple,但即使我用我的 UserDetails 实现来提供它,它也只会返回 null。 I've also tried SecurityContextHolder method which returns anonymousUser(?).
我也尝试过返回anonymousUser(?) 的SecurityContextHolder 方法。 In either way not getting the desired result.
无论哪种方式都没有得到想要的结果。 Tried all of the solutions I could find on internet so far but no luck.
尝试了到目前为止我在互联网上可以找到的所有解决方案,但没有运气。 Controller;
Controller;
@Controller
public class Home {
EntryService entryService;
public Home(EntryService entryService) {
this.entryService = entryService;
}
@GetMapping("/Home")
public String registration(Entry entry, Model model) {
//See what it returns
System.out.println(getUsername());
List<Entry> entries = new ArrayList<>(entryService.getAllEntries());
model.addAttribute("entryList", entries);
model.addAttribute("entry", entry);
return "/home";
}
public String getUsername() {
SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
if (authentication == null)
return null;
Object principal = authentication.getPrincipal();
if (principal instanceof UserDetails) {
return ((UserDetails) principal).getUsername();
} else {
return principal.toString();
}
}
}
Security;安全;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Autowired
public DetailsService detailsService() {
return new DetailsService();
}
protected void configure(HttpSecurity http) throws Exception {
http.
authorizeRequests().
antMatchers("/register").
permitAll().
antMatchers("/home").
hasRole("USER").
and().
csrf().
disable().
formLogin().
loginPage("/").
permitAll().
passwordParameter("password").
usernameParameter("username").
defaultSuccessUrl("/home").
failureUrl("/error").
and().
logout().
logoutUrl("/logout");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(detailsService()).passwordEncoder(passwordEncoder());
}
}
UserDetails;用户详情;
public class UserDetail implements UserDetails {
private final String username;
private final String password;
private final boolean active;
private final List<GrantedAuthority> roles;
public UserDetail(User user) {
this.username = user.getUserName();
this.password = user.getPassword();
this.active = user.getActive();
this.roles = Arrays.stream(user.getRole().toString().split(",")).
map(SimpleGrantedAuthority::new).
collect(Collectors.toList());
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return roles;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return active;
}
}
And UserDetailsService;和 UserDetailsService;
@Service
public class DetailsService implements UserDetailsService {
@Autowired
UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
Optional<User> user = userRepository.findByUserName(s);
user.orElseThrow(() -> new UsernameNotFoundException("User not found"));
return user.map(UserDetail::new).get();
}
}
Using JPA based authentication btw and it works as desired.顺便说一句,使用基于 JPA 的身份验证,它可以按需要工作。
The only reason that you would get anonymousUser in the security context is if you are not authenticated.您在安全上下文中获得 anonymousUser 的唯一原因是您未通过身份验证。 Try adding
.anyRequest().authenticated()
right after hasRole("USER").
尝试在
hasRole("USER").
之后添加.anyRequest().authenticated()
)。 in your SecurityConfig and then you should see the principal in SecurityContextHolder.getContext().getAuthentication()
.在您的 SecurityConfig 中,然后您应该在
SecurityContextHolder.getContext().getAuthentication()
中看到主体。 This will continue to work with the methods you've specified as permitAll()
.这将继续使用您指定为
permitAll()
的方法。
Also, just an observation, but your url matcher in your config is on /home
and your controller specifies a GetMapping of /Home
.另外,只是一个观察,但是您的配置中的 url 匹配器位于
/home
上,并且您的 controller 指定了/Home
的 GetMapping 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.