Önsöz: Spring-Security 3.2'den beri @AuthenticationPrincipal
bu cevabın sonunda güzel bir açıklama var . Spring-Security> = 3.2 kullandığınızda gitmenin en iyi yolu budur.
Sen ne zaman:
- Spring-Security'nin eski bir sürümünü kullanmak,
- özel Kullanıcı Nesnenizi veritabanında depolanan bazı bilgilerle (oturum açma veya kimlik gibi) yüklemeniz gerekir veya
- a
HandlerMethodArgumentResolver
ya da WebArgumentResolver
bunu zarif bir şekilde nasıl çözebileceğini öğrenmek ya da sadece arka planı öğrenmek @AuthenticationPrincipal
ve AuthenticationPrincipalArgumentResolver
(a'ya dayalı olduğu için HandlerMethodArgumentResolver
)
sonra okumaya devam edin - aksi takdirde @AuthenticationPrincipal
Rob Winch (Yazar @AuthenticationPrincipal
) ve Lukas Schmelzeisen'a (cevabı için) kullanın ve teşekkür edin .
(BTW: Cevabım biraz daha eski (Ocak 2012), bu yüzden Spring Security 3.2'deki ek açıklama çözüm tabanına sahip olan ilk olarak Lukas Schmelzeisen oldu @AuthenticationPrincipal
.)
Sonra kumandanızda kullanabilirsiniz
public ModelAndView someRequestHandler(Principal principal) {
User activeUser = (User) ((Authentication) principal).getPrincipal();
...
}
Bir kez ihtiyacınız varsa sorun değil. Ancak birkaç kez çirkin bir şekilde ihtiyacınız varsa, kontrol cihazınızı altyapı detayları ile kirletir, bu normalde çerçeve tarafından gizlenmelidir.
Yani gerçekten isteyebileceğiniz şey, böyle bir denetleyiciye sahip olmaktır:
public ModelAndView someRequestHandler(@ActiveUser User activeUser) {
...
}
Bu nedenle, yalnızca bir WebArgumentResolver
. Bir yöntemi var
Object resolveArgument(MethodParameter methodParameter,
NativeWebRequest webRequest)
throws Exception
Bu, web isteğini (ikinci parametre) alır ve User
yöntem bağımsız değişkeninden (ilk parametre) sorumlu hissediyorsa döndürmelidir .
İlkbahar 3.1'den beri yeni bir kavram var HandlerMethodArgumentResolver
. Spring 3.1+ kullanıyorsanız, kullanmalısınız. (Bu cevabın bir sonraki bölümünde açıklanmaktadır))
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;
}
}
}
Özel Ek Açıklama tanımlamanız gerekir - Kullanıcı'nın her örneğinin her zaman güvenlik bağlamından alınması gerekiyorsa, ancak hiçbir zaman bir komut nesnesi değilse bunu atlayabilirsiniz.
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ActiveUser {}
Yapılandırmada yalnızca şunu eklemeniz gerekir:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"
id="applicationConversionService">
<property name="customArgumentResolver">
<bean class="CurrentUserWebArgumentResolver"/>
</property>
</bean>
@ Bkz: Spring MVC @Controller yöntemi bağımsız değişkenlerini özelleştirmeyi öğrenin
Spring 3.1 kullanıyorsanız, WebArgumentResolver üzerinden HandlerMethodArgumentResolver'ı önerdikleri belirtilmelidir. - Jay'in yorumuna bakın
HandlerMethodArgumentResolver
Bahar 3.1+ için de aynı
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;
}
}
}
Yapılandırmada bunu eklemeniz gerekir
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="CurrentUserHandlerMethodArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
@ Spring MVC 3.1 HandlerMethodArgumentResolver arabirimini kullanma
Spring-Security 3.2 Çözümü
Spring Security 3.2 (Spring 3.2 ile karıştırmayın) kendi çözüm yoluna sahiptir: @AuthenticationPrincipal
( org.springframework.security.web.bind.annotation.AuthenticationPrincipal
). Bu Lukas Schmelzeisen'ın cevabında güzel bir şekilde tanımlandı
Sadece yazıyor
ModelAndView someRequestHandler(@AuthenticationPrincipal User activeUser) {
...
}
Bu çalışmayı elde etmek için AuthenticationPrincipalArgumentResolver
( org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver
): "etkinleştirerek" @EnableWebMvcSecurity
veya bu fasulyeyi içine kaydederek kaydetmeniz gerekir mvc:argument-resolvers
- yukarıda tarif ettiğim şekilde yukarıdaki Spring 3.1 çözümü ile.
@See Spring Security 3.2 Başvurusu, Bölüm 11.2. @AuthenticationPrincipal
Spring-Security 4.0 Çözümü
Bu Bahar 3.2 çözümü gibi çalışır, ancak Bahar 4.0 @AuthenticationPrincipal
ve AuthenticationPrincipalArgumentResolver
bir diğer paketine "taşındı" oldu:
(Ama eski paketlerindeki eski sınıflar hala var, bu yüzden onları karıştırmayın!)
Sadece yazıyor
import org.springframework.security.core.annotation.AuthenticationPrincipal;
ModelAndView someRequestHandler(@AuthenticationPrincipal User activeUser) {
...
}
Bu çalışmayı elde etmek için ( org.springframework.security.web.method.annotation.
) AuthenticationPrincipalArgumentResolver
: "etkinleştirerek" @EnableWebMvcSecurity
veya bu fasulyeyi içine kaydederek kaydetmeniz gerekir mvc:argument-resolvers
- yukarıda tarif ettiğim şekilde yukarıdaki Spring 3.1 çözümü ile.
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver" />
</mvc:argument-resolvers>
</mvc:annotation-driven>
@See Spring Security 5.0 Başvurusu, Bölüm 39.3 @AuthenticationPrincipal