我使用POST方法将Item
添加到使用Spring MVC的数据库中。但每个Item
都有字段userId
,FOREIGN KEY
到users
表。需要知道用户的ID。我使用Spring安全性进行身份验证。可能是有可能通过ServletContext
或HttpSession
获取当前用户的ID,可能是春天安全保存用户的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安全性所以所有细节都隐藏起来,我不知道如何干预auth进程并在授权阶段拦截用户的id。
@Entity(name = "users")
public class User implements UserDetails {...}
@Autowired
private UserService userService;
@Autowired
private void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.userDetailsService(userService);
}
谢谢!
答案 0 :(得分:2)
请尝试这种方法
确保您拥有自己的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 security用户的定义中。
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";
}
答案 1 :(得分:0)
我尝试了很多事情,但是最好的方法是创建扩展org.springframework.security.core.userdetails.User的custer 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();
私下
答案 2 :(得分:0)
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