Lời mở đầu: Kể từ Spring-Security 3.2, có một chú thích hay @AuthenticationPrincipal
được mô tả ở cuối câu trả lời này. Đây là cách tốt nhất để sử dụng khi bạn sử dụng Spring-Security> = 3.2.
Khi bạn:
- sử dụng phiên bản cũ hơn của Spring-Security,
- cần tải Đối tượng người dùng tùy chỉnh của bạn từ Cơ sở dữ liệu bằng một số thông tin (như thông tin đăng nhập hoặc id) được lưu trữ trong hiệu trưởng hoặc
- muốn tìm hiểu làm thế nào một
HandlerMethodArgumentResolver
hoặc WebArgumentResolver
có thể giải quyết điều này một cách tao nhã, hoặc chỉ muốn tìm hiểu nền tảng phía sau @AuthenticationPrincipal
và AuthenticationPrincipalArgumentResolver
(vì nó dựa trên một HandlerMethodArgumentResolver
)
sau đó tiếp tục đọc - khác chỉ cần sử dụng @AuthenticationPrincipal
và cảm ơn Rob Winch (Tác giả @AuthenticationPrincipal
) và Lukas Schmelzeisen (cho câu trả lời của mình).
(BTW: Câu trả lời của tôi đã cũ hơn một chút (tháng 1 năm 2012), do đó, Lukas Schmelzeisen đã trở thành người đầu tiên có @AuthenticationPrincipal
cơ sở giải pháp chú thích trên Spring Security 3.2.)
Sau đó, bạn có thể sử dụng trong bộ điều khiển của bạn
public ModelAndView someRequestHandler(Principal principal) {
User activeUser = (User) ((Authentication) principal).getPrincipal();
...
}
Đó là ok nếu bạn cần nó một lần. Nhưng nếu bạn cần nó nhiều lần vì nó xấu vì nó làm ô nhiễm bộ điều khiển của bạn với các chi tiết cơ sở hạ tầng, điều đó thường sẽ bị ẩn bởi khung.
Vì vậy, những gì bạn có thể thực sự muốn là có một bộ điều khiển như thế này:
public ModelAndView someRequestHandler(@ActiveUser User activeUser) {
...
}
Do đó bạn chỉ cần thực hiện a WebArgumentResolver
. Nó có một phương pháp
Object resolveArgument(MethodParameter methodParameter,
NativeWebRequest webRequest)
throws Exception
Điều đó nhận được yêu cầu web (tham số thứ hai) và phải trả về User
nếu nó cảm thấy có trách nhiệm với đối số phương thức (tham số đầu tiên).
Kể từ mùa xuân 3.1, có một khái niệm mới gọi là HandlerMethodArgumentResolver
. Nếu bạn sử dụng Spring 3.1+ thì bạn nên sử dụng nó. (Nó được mô tả trong phần tiếp theo của câu trả lời này))
public class CurrentUserWebArgumentResolver implements WebArgumentResolver{
Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) {
if(methodParameter is for type User && methodParameter is annotated with @ActiveUser) {
Principal principal = webRequest.getUserPrincipal();
return (User) ((Authentication) principal).getPrincipal();
} else {
return WebArgumentResolver.UNRESOLVED;
}
}
}
Bạn cần xác định Chú thích tùy chỉnh - Bạn có thể bỏ qua nếu mọi trường hợp của Người dùng phải luôn được lấy từ ngữ cảnh bảo mật, nhưng không bao giờ là đối tượng lệnh.
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ActiveUser {}
Trong cấu hình, bạn chỉ cần thêm phần này:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"
id="applicationConversionService">
<property name="customArgumentResolver">
<bean class="CurrentUserWebArgumentResolver"/>
</property>
</bean>
@See: Tìm hiểu để tùy chỉnh các đối số phương thức Spring MVC @Controll
Cần lưu ý rằng nếu bạn đang sử dụng Spring 3.1, họ khuyên dùng HandlerMethodArgumentResolver trên WebArgumentResolver. - xem bình luận của Jay
Tương tự với HandlerMethodArgumentResolver
Spring 3.1+
public class CurrentUserHandlerMethodArgumentResolver
implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return
methodParameter.getParameterAnnotation(ActiveUser.class) != null
&& methodParameter.getParameterType().equals(User.class);
}
@Override
public Object resolveArgument(MethodParameter methodParameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
if (this.supportsParameter(methodParameter)) {
Principal principal = webRequest.getUserPrincipal();
return (User) ((Authentication) principal).getPrincipal();
} else {
return WebArgumentResolver.UNRESOLVED;
}
}
}
Trong cấu hình, bạn cần thêm cái này
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="CurrentUserHandlerMethodArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
@See Tận dụng giao diện Spring MVC 3.1 HandlerMethodArgumentResolver
Giải pháp bảo mật mùa xuân 3.2
Spring Security 3.2 (không nhầm lẫn với Spring 3.2) có giải pháp xây dựng riêng: @AuthenticationPrincipal
( org.springframework.security.web.bind.annotation.AuthenticationPrincipal
). Điều này được mô tả độc đáo trong câu trả lời của Lukas Schmelzeisen
Nó chỉ là viết
ModelAndView someRequestHandler(@AuthenticationPrincipal User activeUser) {
...
}
Để làm việc này, bạn cần đăng ký AuthenticationPrincipalArgumentResolver
( org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver
): bằng cách "kích hoạt" @EnableWebMvcSecurity
hoặc bằng cách đăng ký hạt này trong mvc:argument-resolvers
- giống như cách tôi đã mô tả với giải pháp Spring 3.1 ở trên.
@See Bảo mật mùa xuân 3.2 Tham khảo, Chương 11.2. @AuthenticationPrincipal
Giải pháp bảo mật mùa xuân 4.0
Nó hoạt động giống như giải pháp Spring 3.2, nhưng trong Spring 4.0 @AuthenticationPrincipal
, nó AuthenticationPrincipalArgumentResolver
đã được "chuyển" sang một gói khác:
(Nhưng các lớp cũ trong các gói cũ vẫn tồn tại, vì vậy đừng trộn chúng!)
Nó chỉ là viết
import org.springframework.security.core.annotation.AuthenticationPrincipal;
ModelAndView someRequestHandler(@AuthenticationPrincipal User activeUser) {
...
}
Để làm việc này, bạn cần đăng ký ( org.springframework.security.web.method.annotation.
) AuthenticationPrincipalArgumentResolver
: bằng cách "kích hoạt" @EnableWebMvcSecurity
hoặc bằng cách đăng ký hạt này trong mvc:argument-resolvers
- giống như cách tôi đã mô tả với giải pháp Spring 3.1 ở trên.
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver" />
</mvc:argument-resolvers>
</mvc:annotation-driven>
Tài liệu tham khảo @See Spring Security 5.0, Chương 39.3 @AuthenticationPrincipal