SORU
6 Ocak 2012, Cuma


Nasıl'In UserDetails kullanıcı aktif hale getirmek için

Aktif (giriş) kullanıcı ihtiyacım olduğunda benim denetleyicileri,, UserDetails benim uygulama almak için aşağıdaki yapıyorum:

User activeUser = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
log.debug(activeUser.getSomeCustomField());

Gayet iyi çalışıyor, ama Bahar bu gibi bir durumda hayat daha kolay yapabilir diye düşünüyorum. Bir şekilde denetleyici veya yönteme UserDetails autowired gerek var mı?

Örneğin, gibi bir şey

public ModelAndView someRequestHandler(Principal principal) { ... }

Ama yerine ** 15 UserDetails bir yerine?

Zarif bir çözüm arıyorum. Herhangi bir fikir?

CEVAP
7 Ocak 2012, CUMARTESİ


Önsöz:Bahar-Güvenlik 3.2 beri 17 ** güzel bir açıklama bu cevap sonunda açıklanmıştır. Bu Bahar-Güvenlik ^ kullandığınızda gitmek için en iyi yoldur . = 3.2.

Ne zaman:

  • Bahar-Güvenlik, eski bir sürümü kullanın
  • bazı bilgileri (oturum açma kimliği) Müdür tarafından depolanan veritabanından özel bir Kullanıcı Nesnesi yüklemek gerekiyor ya
  • öğrenmek istiyorum nasıl bir HandlerMethodArgumentResolver WebArgumentResolver çözebilir bu zarif bir şekilde, ya da sadece öğrenmek için bir arka plan arkasında @AuthenticationPrincipal AuthenticationPrincipalArgumentResolver (çünkü dayalı * HandlerMethodArgumentResolver)

o zaman okumaya devam edin - başka @AuthenticationPrincipal kullanın ve Rob Vinç (@AuthenticationPrincipal Yazar) ve Lukas Schmelzeisen için teşekkür ederim (cevap için).

(BTW: Benim cevabım biraz daha büyük (Ocak 2012), öyle oldu Lukas Schmelzeisen gelip olarak ilki ile @AuthenticationPrincipal açıklama çözüm Bankası Bahar Güvenlik 3.2.)


Sonra kumandanız olarak kullanabilirsiniz

public ModelAndView someRequestHandler(Principal principal) {
   User activeUser = (User) ((Authentication) principal).getPrincipal();
   ...
}

Eğer bir kere ihtiyacın varsa Tamam. Ama eğer altyapı detayları ile kontrolün kirletiyor çünkü birkaç kez onun çirkin gerekirse, normalde çerçevesi tarafından gizli olmalıdır.

Yani gerçekten istediğiniz ne olabilir böyle bir kumanda var

public ModelAndView someRequestHandler(@ActiveUser User activeUser) {
   ...
}

Bu nedenle sadece WebArgumentResolver uygulamak gerekir. Bir yöntemi vardır

Object resolveArgument(MethodParameter methodParameter,
                   NativeWebRequest webRequest)
                   throws Exception

Bu web isteği (ikinci parametre) ve eğer onun yöntemi argüman (ilk parametre) sorumlu hissederse User iade etmelidir.

Bahar 3.1 beri yeni bir konsept HandlerMethodArgumentResolver denir. Eğer Bahar 3.1 kullanıyorsanız, o zaman kullanmanız gerekir. (Bir sonraki bölümde bu yanıt) olarak tarif edilir)

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

Eğer Kullanıcı her örneği her zaman güvenlik bağlamında alınması gereken atlayabilirsiniz Özel ek Açıklama -- tanımlamak gerekir, ama hiç bir komut nesnesi.

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ActiveUser {}

Yapılandırma sadece şunu eklemek gerekir:

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"
    id="applicationConversionService">
    <property name="customArgumentResolver">
        <bean class="CurrentUserWebArgumentResolver"/>
    </property>
</bean>

@Bakın: Learn to customize Spring MVC @Controller method arguments

Eğer onlar tavsiye 3.1, Bahar kullanıyorsanız WebArgumentResolver üzerinde HandlerMethodArgumentResolver unutulmamalıdır. - Jay yorum bakın


Bahar 3.1 HandlerMethodArgumentResolver ile 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ırma bu eklemek gerekir

<mvc:annotation-driven>
      <mvc:argument-resolvers>
           <bean class="CurrentUserHandlerMethodArgumentResolver"/>         
      </mvc:argument-resolvers>
 </mvc:annotation-driven>

@Leveraging the Spring MVC 3.1 HandlerMethodArgumentResolver interface bkz


Bahar-Güvenlik 3.2 Çözüm

Bahar Güvenlik 3.2 (Bahar 3.2 ile karıştırmayın) kendi yapı vardır çözüm: @AuthenticationPrincipal. Bu güzel Lukas Schmelzeisen`s answer açıklanmıştır

Sadece yazı

ModelAndView someRequestHandler(@AuthenticationPrincipal User activeUser) {
    ...
 }

Bu almak için çalışmak gerekir kaydetmek için AuthenticationPrincipalArgumentResolver: ya "aktive" @EnableWebMvcSecurity veya kaydetme bu fasulye içinde mvc:argument-resolvers - aynı şekilde ben tarif ile Mayıs Bahar 3.1 çözüm yukarıda.

@Spring Security 3.2 Reference, Chapter 11.2. @AuthenticationPrincipal bkz

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Mega64

    Mega64

    24 ŞUBAT 2006
  • ModNation Racers H.Q.

    ModNation Ra

    31 Ocak 2010
  • olinerd

    olinerd

    23 AĞUSTOS 2007