Spring启动:使用MongoDB创建用户

时间:2017-03-21 12:58:33

标签: spring mongodb rest spring-boot spring-security

好的,我有一个问题:

  

如何使用spring创建用户?

我学习了一些信息,最好的方法就是使用UserDetails ...... 但我找不到使用和良好做法的信息:UserDetails with mongodb。

  

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

我还有一个关于休息安全的问题:

  

我有弹簧的其余模块但是如何用户保护存储库?我的意思是,每个登录用户只能查看/编辑他是所有者的内容。

使用rest模块,您可以使用Spring安全性角色保护路径,但无法为用户分配资源。 (我的意思是用户详细信息)

我真的需要帮助,因为它是一个框架,我不想重做什么春天,因为它是一个框架......但我是新的!

如果你想了解更多细节,我可以准确地说出你不明白但我是法国人,所以我的英语并不完美。

1 个答案:

答案 0 :(得分:1)

我认为this answer可以帮助您解决问题,即使您没有使用Spring Data MongoDB。

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

然后你需要自己实现一个UserDetails POJO(有很多例子)。

最后,您需要使用自定义UserService配置Spring Security,这对于Spring Boot来说非常简单。

因此,如果您还没有使用Spring Boot,我强烈建议您这样做。它使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 Security注释并使用SPEL(Spring Expression Language)来评估条件:

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

因此,只要Controller找到此@MyUser注释,它就会调用此WebArgumentResolver来检索当前用户详细信息(SecUserDetails实例)并将其注入控制器方法。

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