我認爲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
(春季表達式語言)評估條件:
@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'我不知道如何控制它們! :c –
您不一定需要'spring-boot-starter-data-rest',您可以使用'spring-boot-starter-data'(Spring Data)創建您自己的Repository接口並從MongoRepository '。 –