如何使用Spring MVC获取用户ID?



我使用 POST 方法将Item添加到带有 Spring MVC 的数据库中。但是每个Item都有字段userId,它FOREIGN KEYusers表。需要知道用户的ID。我使用 Spring 安全性进行身份验证。可能有可能用ServletContextHttpSession获取当前用户的ID,可能是spring安全将用户ID保存在某处?

如何识别使用Spring MVC向服务器请求数据库数据的用户?

@PostMapping("/get_all_items/add_item_page/add_item")
public String addItem(@RequestParam(value = "description")
final String description) {
final Item item = new Item();
item.setDescription(description);
item.setAuthorId(/* ??? */);
service.add(item);
return "redirect:get_all_items";
}

使用UserDetails实现Spring安全实现,因此所有细节都对我隐藏,我不知道如何在授权过程中干预并在创作阶段拦截用户的ID。

@Entity(name = "users")
public class User implements UserDetails {...}
@Autowired
private UserService userService;
@Autowired
private void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.userDetailsService(userService);
}

谢谢!

请尝试使用此方法

确保您有自己的Userpojo课程

@Entity
public class MyUser {
@Id
private Long id;
private String username;
private String password;
private boolean isEnabled;
@ManyToMany
private List<MyAuthority> myAuthorities;
...
}

也是一个Authoritypojo,用于定义用户角色

@Entity
public class MyAuthority {
@Id
private int id;
private String name; .....

然后是用户存储库,在这个例子中,我只是声明一个按用户名查找的方法,并获取一个 Optional 来验证用户是否存在。

public interface MyUserRepository extends CrudRepository<MyUser,Long> {
public Optional<MyUser> findFirstByUsername(String username);
}

创建一个从org.springframework.security.core.userdetails.User扩展的用户类,以便将您的自定义用户包装在 Spring 安全用户的定义中。

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import java.util.Collection;
public class MySpringUser  extends User {
private MyUser user;
public MySpringUser(MyUser myUser, Collection<? extends GrantedAuthority> authorities) {
super(myUser.getUsername(), myUser.getPassword(), myUser.isEnabled()
, true, true, true, authorities);
this.setUser(myUser);   
}
public MyUser getUser() {
return user;
}
public void setUser(MyUser user) {
this.user = user;
}
}

现在UserDetailService实现,只有一种方法可以实现loadUserByUsername这里是需要MyUserRepository的地方,以便通过用户名从存储库中检索用户信息。

@Service
public class MyUserService implements UserDetailsService {
@Autowired
MyUserRepository myUserRepository;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
Optional<MyUser> myUser = myUserRepository.findFirstByUsername(s);
return myUser.map( (user) -> {
return new MySpringUser(
user,
user.getMyAuthorities().stream().
map( authority ->
new SimpleGrantedAuthority(authority.getName())).
collect(Collectors.toList()));
}).orElseThrow(() -> new UsernameNotFoundException("user not found"));
}
}

现在你可以注入UserDetailService,因为它的实现将从类MyUserService注入。

@Autowired
private UserService userService;
@Autowired
private void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.userDetailsService(userService);
}

然后使用这种方法可以将Principal对象注入控制器,并且在方法内部可以将Principal对象强制转换为MySpringUser,这是因为MySpringUser是从org.springframework.security.core.userdetails.User扩展而来的,并且User类实现了UserDetails接口。 当然,您可以获取用户的所有其他自定义字段,因为它的定义包含在org.springframework.security.core.userdetails.User类中

@PostMapping("/get_all_items/add_item_page/add_item")
public String addItem(@RequestParam(value = "description")
final String description, Principal principal) {
MySpringUser mySpringUser = (MySpringUser)principal;
final Item item = new Item();
item.setDescription(description);
item.setAuthorId(mySpringUser.getUser().getId());
service.add(item);
return "redirect:get_all_items";
}

我已经尝试了很多事情,但最好的办法是创建扩展org.springframework.security.core.userdetails.User

package com.walterwhites.library.model.pojo;
import lombok.Getter;
import lombok.Setter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import java.util.Collection;
@Getter
@Setter
public class MyUser extends User {
long id;
public MyUser(long id, String username, String password, Collection<? extends GrantedAuthority> authorities) {
super(username, password, authorities);
this.id = id;
}
}

之后你可以像下面这样使用

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
UserDetails client = (UserDetails) auth.getPrincipal();
long id =  ((MyUser) client).getId();

亲切

UserDetails client = (UserDetails) auth.getPrincipal(); 
long id = ((User) client).getUserId();    
System.out.println(id); 

我收到此错误:

java.lang.ClassCastException: com.doc.importexport.implementation.UserPrincipal cannot be cast to com.doc.importexport.model.User

最新更新