Spring引导:使用MongoDB创建用户

Spring引导:使用MongoDB创建用户,spring,mongodb,rest,spring-boot,spring-security,Spring,Mongodb,Rest,Spring Boot,Spring Security,好吧,我有个问题: 如何使用spring创建用户 我学到了一些信息,最好的方法就是使用UserDetails。。。 但是我找不到可用于良好实践的信息:UserDetails 当我有我的UserDetails时,如何创建正确的注册/登录rest方法 我还有一个关于rest安全性的问题: 我有带spring的rest模块,但是如何通过用户保护存储库?我的意思是,每个登录用户只能查看/编辑其所有者的内容 使用rest模块,您可以使用具有Spring security的角色保护路径,但不能将ressou

好吧,我有个问题:

如何使用spring创建用户

我学到了一些信息,最好的方法就是使用UserDetails。。。 但是我找不到可用于良好实践的信息:UserDetails

当我有我的UserDetails时,如何创建正确的注册/登录rest方法

我还有一个关于rest安全性的问题:

我有带spring的rest模块,但是如何通过用户保护存储库?我的意思是,每个登录用户只能查看/编辑其所有者的内容

使用rest模块,您可以使用具有Spring security的角色保护路径,但不能将ressource分配给用户。(我指的是用户详细信息)

我真的需要帮助,因为它是一个框架,我不想重做spring做的事情,因为它是一个框架。。。但我是新手

如果你想要更多的细节,我可以精确地说出你不懂的地方,但我是法国人,所以我的英语并不完美

我认为它可以帮助您解决问题,即使您不使用Spring Data MongoDB

基本上,您需要实现
UserDetailsService
接口,并将其注释为
@Component
@Service
bean

然后,您需要自己实现一个
UserDetails
POJO(有许多示例)

最后,您需要使用自定义用户服务配置Spring安全性,这在Spring引导中非常容易

因此,如果您还没有使用
springboot
,我强烈建议您这样做。它让Spring开发者的生活变得更加轻松

为了保护REST端点的安全,您可以创建某种类型的
PermissionService
(常规的Spring
@Service
bean),用于检查是否允许当前用户访问/编辑资源

例如:

@Slf4j
@Service
public class PermissionService {

    public boolean hasPermission(String userId, String resourceId) {
        log.debug("Checking permission for [{}] on resource [{}]", userId, resourceId);

        hasText(userId);
        hasText(resourceId);

        return resourceId == 1;
    }
}
在任何
@RestController
中,您现在可以添加一个Spring安全注释,并使用
SPEL
(Spring表达式语言)来评估条件:

@RestController
@RequestMapping("/api/resource")
public class ResourceController {

    @GetMapping("/{id}")
    @PreAuthorize("@permissionService.hasPermission(userDetails.userId, resourceId)")
    public ResponseEntity findResource(@PathVariable("id") String resourceId, @MyUser SecUserDetails userDetails) {
        return ResponseEntity.ok(resourceRepository.findById(resourceId));
    }
}
现在,你一定在想:这个奇怪的
@MyUser
注释是什么?这是一个自定义注释,可以将当前的Spring Security UserDetails实例注入控制器方法

您可以这样定义一个:

@Slf4j
@Component
public class MyUserMethodArgumentResolver implements HandlerMethodArgumentResolver {

    private final UserService userService;

    @Autowired
    public MyUserMethodArgumentResolver(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.getParameterAnnotation(MyUser.class) != null
        && methodParameter.getParameterType().equals(SecUserDetails.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
    WebDataBinderFactory binderFactory) throws Exception {
        if (this.supportsParameter(methodParameter)) {
            return this.userService.getCurrentUser();
        } else {
            return WebArgumentResolver.UNRESOLVED;
        }
    }
}
因此,每当控制器找到此
@MyUser
注释时,它都会调用此WebArgumentResolver来检索当前用户详细信息(
SecUserDetails
实例),并将其注入控制器方法


然后可以在
PermissionService
中使用它来检查访问。

问题是
org.springframework.boot:spring boot starter data rest
使用
MongoRepository
自动生成所有资源的rest路径,我不知道如何控制它们!:您不一定需要
spring boot starter数据rest
,您只需使用
spring boot starter数据
(spring数据),在这里您可以创建自己的存储库接口并从
MongoRepository
进行扩展。