Java 手动设置已验证的Spring用户

Java 手动设置已验证的Spring用户,java,spring,spring-boot,spring-security,Java,Spring,Spring Boot,Spring Security,我正在构建一个SpringBoot应用程序 我正在使用Spring Security,并且有一个UserDetailsService实现设置: public class MyUserDetailService implements UserDetailsService { @Autowired private UserService userService; @Override public UserDetails loadUserByUsername(Str

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

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

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;
    }

}
公共类MyUserDetailService实现UserDetailsService{
@自动连线
私人用户服务;
@凌驾
public UserDetails loadUserByUsername(字符串用户名)引发UsernameNotFoundException{
org.springframework.security.core.userdetails.User springUser=null;
User=userService.loadUserByUsername(用户名);
如果(用户!=null){
列表权限=空;
List roles=user.getRoles();
if(角色!=null){
authorities=newarraylist();
for(角色当前角色:角色){
添加(新的SimpleGrantedAuthority(currentRole.name());
}
}
springUser=new org.springframework.security.core.userdetails.User(User.getUsername(),User.getPassword(),authorities);
}
返回用户;
}
}
我有一个服务层,其中包含将用户添加到数据库的方法:

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);

}
公共接口用户服务{
公共长addStandardUser(字符串名、字符串名、字符串用户名、字符串密码);
@预授权(“hasRole('ADMIN')”)
public Long addAdministratorUser(字符串firstName、字符串lastName、字符串用户名、字符串密码);
@预授权(“hasRole('ADMIN')”)
公共用户loadUserByUsername(字符串用户名);
公共Iterable getUsers(int pageNumber、int pageSize、方向、字符串排序);
}
我还有一个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!");
    }
}
@组件
@简介(“开发”)
公共类DBInitializer实现CommandLineRunner{
@自动连线
私人用户服务;
@凌驾
公共无效运行(字符串…参数)引发异常{
列表权限=新建ArrayList();
添加(新的SimpleGrantedAuthority(“管理”);
身份验证=新用户名PasswordAuthenticationToken(“foo”,null,authorities);
SecurityContextHolder.getContext().setAuthentication(身份验证);
addAdministratorUser(“John”、“Doe”、“jdoe”、“1234”);
System.out.println(“完成!”);
}
}
问题是,当我尝试添加用户时,CommandLineRunner中的Spring出现了一个拒绝访问的异常。我假设问题在于我手动错误地“注入”了Spring用户。addAdminUser()方法必须由管理员角色的用户运行,因此我需要临时以管理员用户的身份运行。我知道有一个@RunAs注释我记得在其他J2EE应用程序中使用过,但我不确定它是如何与Spring应用程序接口的,或者它是否完全用于不同的上下文中

...
// The default role prefix starts with `ROLE_`
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
...
更多详细信息请参见

可能的副本