手动设置经过身份验证的 Spring 用户

use*_*644 5 java spring spring-security spring-boot

我正在构建一个 SpringBoot 应用程序。

我正在使用 Spring Security,并且有一个 UserDetailsS​​ervice 实现设置:

public class MyUserDetailService implements UserDetailsService {

    @Autowired
    private UserService userService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        org.springframework.security.core.userdetails.User springUser = null;
        User user = userService.loadUserByUsername(username);
        if(user != null){
            List<SimpleGrantedAuthority> authorities = null;
            List<Role> roles = user.getRoles();
            if(roles != null){
                authorities = new ArrayList<>();
                for(Role currentRole: roles){
                    authorities.add(new SimpleGrantedAuthority(currentRole.name()));
                }
            }
            springUser = new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), authorities);
        }
        return springUser;
    }

}
Run Code Online (Sandbox Code Playgroud)

我有一个服务层,其中包含将用户添加到数据库的方法:

public interface UserService {

    public Long addStandardUser(String firstName, String lastName, String username, String password);

    @PreAuthorize("hasRole('ADMIN')")
    public Long addAdministratorUser(String firstName, String lastName, String username, String password);

    @PreAuthorize("hasRole('ADMIN')")
    public User loadUserByUsername(String username);

    public Iterable<User> getUsers(int pageNumber, int pageSize, Direction direction, String sort);

}
Run Code Online (Sandbox Code Playgroud)

我还有一个 CommandLineRunner 实现,我使用它(在开发模式下)使用示例用户初始化数据库:

@Component
@Profile("dev")
public class DBInitializer implements CommandLineRunner {

    @Autowired
    private UserService userService;

    @Override
    public void run(String... args) throws Exception {
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority("ADMIN"));
        Authentication authentication =  new UsernamePasswordAuthenticationToken("foo", null, authorities);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        userService.addAdministratorUser("John", "Doe", "jdoe", "1234");
        System.out.println("done!");
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,当我尝试添加用户时,我在 CommandLineRunner 中收到来自 Spring 的访问被拒绝异常。我假设问题是我错误地手动“注入”了 Spring 用户。addAdminUser() 方法必须由 ADMIN 角色的用户运行,因此我需要暂时以 ADMIN 用户身份运行。我知道有一个 @RunAs 注释,我记得在其他 J2EE 应用程序中使用过,但我不确定它如何与 Spring 应用程序交互,或者是否完全在不同的上下文中使用

cha*_*luo 3

...
// The default role prefix starts with `ROLE_`
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
...
Run Code Online (Sandbox Code Playgroud)

更详细的请看这里