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

时间:2017-08-23 00:05:22

标签: java spring spring-mvc

我使用POST方法将Item添加到使用Spring MVC的数据库中。但每个Item都有字段userIdFOREIGN KEYusers表。需要知道用户的ID。我使用Spring安全性进行身份验证。可能是有可能通过ServletContextHttpSession获取当前用户的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);
}

谢谢!

3 个答案:

答案 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,这是因为MySpringUserorg.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