我使用 POST 方法将Item
添加到带有 Spring MVC 的数据库中。但是每个Item
都有字段userId
,它FOREIGN KEY
users
表。需要知道用户的ID。我使用 Spring 安全性进行身份验证。可能有可能用ServletContext
或HttpSession
获取当前用户的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);
}
谢谢!
请尝试使用此方法
确保您有自己的User
pojo课程
@Entity
public class MyUser {
@Id
private Long id;
private String username;
private String password;
private boolean isEnabled;
@ManyToMany
private List<MyAuthority> myAuthorities;
...
}
也是一个Authority
pojo,用于定义用户角色
@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