2017-06-08 1 views
1

現在、私は豆の工場を通してそれを得ることが可能であるならば、私はこの春:注射により、現在のユーザーを取得し

@Service 
class UserProvider implements BeanFactoryAware { 
    BeanFactory beanFactory; 

    public Principal get(){ 
     return (Principal) beanFactory.getBean("Principal"); 
    } 

    @Override 
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException { 
     this.beanFactory = beanFactory; 
    } 
} 

ないように、不思議通常

SecurityContextHolder.getContext().getAuthentication().getPrincipal 

でユーザーを取得していますSpringは、現在の認証されたユーザーを含むセッションスコープのBeanを格納しますか?

+0

あなたはそれを格納するためにそれを告げた場合はそれがありません。あるいは、他のいくつかの豆がそれに依存している場合、私は推測します。 –

+1

これは不可能です。 Spring MVC Controllerでメソッドの引数として 'Principal'を使うことはできますが、@ Autowireできません。 (そしてそれはまた悪いアイホーです)。参照を行う簡単なヘルパークラスを作成し、ユーザー(MVCパーツの外)が必要な場所から呼び出すことができます。 –

+0

なぜこれが必要ですか? – eg04lt3r

答えて

1

あなたが使用することができますにセッションスコープのBeanを注入している場合は、プロキシの世話をするあなたのカスタムビーンポストプロセッサーと動的プロキシーを組み合わせて使用​​するこれを行う。

ような何か:

@SpringBootApplication 
public class So44435897Application { 

    public static void main(String[] args) { 
     SpringApplication.run(So44435897Application.class, args); 
    } 

    @Retention(RetentionPolicy.RUNTIME) 
    @Target(ElementType.FIELD) 
    public @interface ApplicationUser { } 

    @Component 
    public static class CurrentUserBeanPostProcessor implements BeanPostProcessor { 
     @Override 
     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 
      ReflectionUtils.doWithFields(bean.getClass(), field -> { 
       ReflectionUtils.makeAccessible(field); 
       if (field.getAnnotation(ApplicationUser.class) != null) { 
        final Object proxyInstance = Proxy.newProxyInstance(bean.getClass().getClassLoader(), 
          new Class[] { UserDetails.class }, (proxy, method, args) -> { 
           Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 
           if (authentication != null && authentication.isAuthenticated()) { 
            final Object principal = authentication.getPrincipal(); 
            return method.invoke(principal, args); 
           } 
           throw new NullPointerException(); 
          }); 
        field.set(bean, proxyInstance); 
       } 
      }); 
      return bean; 
     } 

     @Override 
     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 
      return bean; 
     } 
    } 

    @RestController 
    public static class HomeController { 
     final UserService userService; 

     @Autowired 
     public HomeController(UserService userService) { 
      this.userService = userService; 
     } 

     @GetMapping 
     public String me() { 
      return userService.getName(); 
     } 
    } 

    @Service 
    public static class UserService { 
     @ApplicationUser 
     UserDetails user; 

     String getName() { 
      return user.getUsername(); 
     } 
    } 
} 

=>

$ curl -u admin:admin -XGET 'localhost:8080' 
admin% 
1

セッションスコープのBeanを定義することは可能です。

定義

@Component 
@Scope("session") 
public class User { 
    init 
} 

使用

@Service 
public UserService { 
    @Autowire 
    User user; 
} 

NOTEあなたは非スコープ

@Scope(value="session", proxyMode=ScopedProxyMode.???) 
+0

実際に私は自分のUser Beanを定義せずに、Springがすでに提供しているPrincipalを注入したいと思っています –

+0

スコープのないBeanを非スコープに注入する場合は、プロキシに注意してください –

関連する問題