[英]Getting currently logged in user
我正在嘗試在我的 Spring Boot 項目中獲取當前登錄的用戶。 我的實體及其關系如下:-
用戶.java
@Entity
@Table(name = "user_account")
public class User {
@Id
@Column(unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String email;
private String username;
private String userType;
@OneToOne(mappedBy = "user")
private BankUserDetails bankUserDetails;
@OneToOne(mappedBy ="user")
private SctUserDetails sctUserDetails;
@Column(length = 60)
private String password;
private boolean enabled;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "users_roles", joinColumns =
@JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "role_id",
referencedColumnName = "id"))
private Collection<Role> roles;
public User() {
super();
this.enabled = true;
}
}
角色.java
@Entity
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToMany(mappedBy = "roles")
private Collection<User> users;
@ManyToMany()
@JoinTable(name = "roles_privileges", joinColumns =
@JoinColumn(name = "role_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "privilege_id",
referencedColumnName = "id"))
private Collection<Privilege> privileges;
private String name;
public Role() {
super();
}
public Role(final String name) {
super();
this.name = name;
}
}
權限.java
@Entity
public class Privilege {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
@ManyToMany(mappedBy = "privileges")
private Collection<Role> roles;
public Privilege() {
super();
}
public Privilege(final String name) {
super();
this.name = name;
}
所以在我的控制器上(現在)我試圖像這樣打印當前登錄的用戶:-
@RequestMapping("/admin")
public String adminPage(Model model){
System.out.println("logged user "+UserController.getLoggedInUser());
return "admin";
}
在我的 UserController 類上,我定義了一個靜態方法來檢索當前登錄的用戶,如下所示:-
public static String getLoggedInUser(){
String username = null;
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if(principal instanceof UserDetails){
username = ((UserDetails) principal).getUsername();
}else {
username = principal.toString();
}
return username;
}
我的 spring 安全配置類如下所示:-
@Configuration
@ComponentScan(basePackages = { "com.infodev.pcms.security" })
@EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyUserDetailsService userDetailsService;
@Autowired
private AuthenticationSuccessHandler myAuthenticationSuccessHandler;
@Autowired
private CustomLogoutSuccessHandler myLogoutSuccessHandler;
@Autowired
private AuthenticationFailureHandler authenticationFailureHandler;
/*@Autowired
private CustomWebAuthenticationDetailsSource authenticationDetailsSource;*/
private BCryptPasswordEncoder passwordEncoder() {
return SecurityUtils.passwordEncoder();
}
@Autowired
private UserRepository userRepository;
public SecSecurityConfig() {
super();
}
private static final String[] PUBLIC_MATCHERS = {
"/css/**",
"/js/**",
"/images/**",
"**/",
"/newUser",
"/forgetPassword",
"/login",
"/uploads/**",
"/assets/**",
"/api/updateCardStatus"
};
@Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider());
}
@Override
public void configure(final WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**","/listAllUsers/**");
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
/* antMatchers("/**").*/
.antMatchers(PUBLIC_MATCHERS).
permitAll().anyRequest().authenticated();
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/login*","/login*", "/logout*", "/signin/**",
"/signup/**", "/customLogin",
"/user/registration*", "/registrationConfirm*",
"/expiredAccount*", "/registration*",
"/badUser*", "/user/resendRegistrationToken*" ,
"/forgetPassword*", "/user/resetPassword*",
"/user/changePassword*", "/emailError*", "/resources/**",
"/old/user/registration*","/successRegister*","/qrcode*").permitAll()
.antMatchers("/invalidSession*").anonymous()
.antMatchers("/user/updatePassword*","/user/savePassword*","/updatePassword*")
.hasAuthority("CHANGE_PASSWORD_PRIVILEGE")
.anyRequest().hasAuthority("READ_PRIVILEGE")
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/homepage.html")
.failureUrl("/login?error=true")
.successHandler(myAuthenticationSuccessHandler)
.failureHandler(authenticationFailureHandler)
.permitAll()
.and()
.sessionManagement()
.invalidSessionUrl("/invalidSession.html")
.maximumSessions(1).sessionRegistry(sessionRegistry()).and()
.sessionFixation().none()
.and()
.logout()
.logoutSuccessHandler(myLogoutSuccessHandler)
.invalidateHttpSession(false)
.deleteCookies("JSESSIONID")
.permitAll();
}
// beans
@Bean
public DaoAuthenticationProvider authProvider() {
final CustomAuthenticationProvider authProvider =
new CustomAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Bean
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
}
我的自定義用戶詳細信息
@Override
public UserDetails loadUserByUsername(final String username)
throws UsernameNotFoundException {
final String ip = getClientIP();
if (loginAttemptService.isBlocked(ip)) {
throw new RuntimeException("blocked");
}
try {
final User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException
("No user found with username: " + username);
}
org.springframework.security.core.userdetails.User usr=
new org.springframework.security.core.userdetails.User
(user.getUsername(), user.getPassword(), user.isEnabled(),
true, true, true, getAuthorities(user.getRoles()));
return usr;
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
// UTIL
private final Collection<? extends GrantedAuthority>
getAuthorities(final Collection<Role> roles) {
return getGrantedAuthorities(getPrivileges(roles));
}
private final List<String> getPrivileges(final Collection<Role> roles) {
final List<String> privileges = new ArrayList<String>();
final List<Privilege> collection = new ArrayList<Privilege>();
for (final Role role : roles) {
collection.addAll(role.getPrivileges());
}
for (final Privilege item : collection) {
privileges.add(item.getName());
}
return privileges;
}
private final List<GrantedAuthority> getGrantedAuthorities
(final List<String> privileges) {
final List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (final String privilege : privileges) {
authorities.add(new SimpleGrantedAuthority(privilege));
}
return authorities;
}
當adminPage
方法調用它按預期調用getLoggedInUser()
但它不會進入if(principal instanceof UserDetails){
行。 相反,它將執行 else 子句並返回整個user
對象。
我需要在我的控制器上獲取當前登錄的用戶。 我該怎么做 ?
你應該閱讀這個。 然而,你幾乎就在那里。
代替
SecurityContextHolder.getContext().getAuthentication().getPrincipal()
,你應該使用
SecurityContextHolder.getContext().getAuthentication().getName()
, 進而
userDetailsService.loadUserByUsername(name)
會給你 UserDetails。
或者
只需像這樣修改您的代碼:
@RequestMapping("/admin")
public String adminPage(Principal principal, Model model)
spring 將為您注入主體,檢查主體包含的內容,並在必要時執行我上面建議的相同操作(使用登錄用戶的名稱加載 UserDetails)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.