簡體   English   中英

@EJB注入到Custom UserdetailsS​​ervice中(實現Spring Security UserDetailsS​​ervice)

[英]@EJB injection in a Custom UserdetailsService (implementing Spring Security UserDetailsService)

我在應用程序的JPA / EJB 3 / JSF 2 / Spring Security 3中使用glassfish 3.1.2。 我想編寫一個像這樣的自定義UserdetailsS​​ervice:

import org.apache.log4j.Logger;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
    public class MyUserDetailsService implements UserDetailsService {

        private static final Logger logger = Logger.getLogger(MyUserDetailsService.class);
        @EJB
        private CollaborateurFacadeLocal collaborateurFacade;

        @Override
        public UserDetails loadUserByUsername(String userName) {
            Collaborateur collab = getUser(userName);
            if (collab == null) {
                throw new UsernameNotFoundException(userName + " not found");
            }
            User user = new User(collab);
            if (user == null) {
                throw new UsernameNotFoundException(userName + " not found");
            }
            return user;
        }
    }

所以我試圖在我的MyUserDetailsS​​ervice中注入一個EJB,以便能夠在我的Spring Security上下文文件:“ applicationContext-security.xml”中將它用作身份驗證提供者:

<authentication-manager>
        <authentication-provider user-service-ref="myUserDetailsService">
        </authentication-provider>
    </authentication-manager>

問題是,我陷入了由null的合作商身份導致的NullPointerException。

我嘗試了幾件事,其中包括:

  • Loooking了使用上下文(如一個選址的EJB 這里 ):解決方案的工作,但是這不是我想要的:因為EJB的名字是受到修改。

  • 將類MyUserDetailsS​​ervice放置為JSF 2托管Bean時,collaborateFacade一直保持為空。

  • 將類MyUserDetailsS​​ervice放置為JSF 2受管bean並具有ApplicationScoped范圍,collaborateFacade一直保持為空。

問題:是否有任何干凈的方法將EJB注入MyUserDetailsS​​ervice類中?

我知道我可以使用@Service注釋對類進行注釋(請參閱此鏈接 ),然后我會陷入EJB和Spring的混合使用,這是我不想要的

這是一個簡單的例子, 理論上應該可以工作

  1. 將其添加到您的上下文配置中
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor">  
    <property name=”alwaysUseJndiLookup” value=”true” />  
</bean>  

2.我猜您有一個本地EJB,因為您嘗試使用@EJB注釋。 您必須為EJB提供一個映射名稱。 例如無狀態使用

@Stateless(name = "ejb/CollaborateurFacade", mappedName = "ejb/CollaborateurFacade")
class CollaboratorFacade {}

3.在Spring bean中使用maptedName

@EJB(mappedName = "ejb/CollaborateurFacade")
private CollaborateurFacadeLocal collaborateurFacade;

我知道您曾寫道EJB的名稱是一個需要修改的主題,但是我看不出如何避免嘗試這樣做的方式。

還有另一種可能的解決方案(基於xml!) http://czetsuya-tech.blogspot.ca/2012/05/how-to-call-stateless-ejb-from-spring.html

我想通過以下方式解決問題:不重命名我的Facade(EJB),而必須使用在類注釋@EJB中定義的名稱查找EJB。 然后我的UserDetailsS​​ervice變成這樣:

@EJB(name = "collaborateurFacadeLocal", beanInterface = CollaborateurFacadeLocal.class)
public class SiUserDetailsService implements UserDetailsService {

    private static final Logger logger = Logger.getLogger(SiUserDetailsService.class);
    private CollaborateurFacadeLocal collaborateurFacade;

    private static final String COLLABORATEUR_EJB_LOOKUP_PATH = "java:comp/env/collaborateurFacadeLocal";

    @Override
    public UserDetails loadUserByUsername(String userName) {
        User user;
        Collaborateur collab = getUser(userName);
        if (collab == null) {
            throw new UsernameNotFoundException(userName + " not found");
        }
        user = new User(collab);
        if (user == null) {
            throw new UsernameNotFoundException(userName + " not found");
        }
        return user;
    }

    private Collaborateur getUser(String userName) {
        try {
            InitialContext initialContext = new InitialContext();
            collaborateurFacade = (CollaborateurFacadeLocal) initialContext.lookup(COLLABORATEUR_EJB_LOOKUP_PATH);
            return collaborateurFacade.findUserByUserName(userName);
        } catch (NamingException ex) {
            logger.error("Could not lookup for EJB CollaborateurFacadeLocal with lookup path " + COLLABORATEUR_EJB_LOOKUP_PATH);
        }
        return null;
    }
}

java:comp / env / collaborateurFacadeLocal中的collaborateurFacadeLocal是@EJB(name =批注中的一個,將其與屬性@EJB(name =

這條路:

  • 如果外觀名稱已更改,則SiUserDetailsS​​ervice中將出現編譯錯誤,並且僅在siUserDetailsS​​ervice類中更改其名稱時,查找仍將起作用。
  • 如果耳朵名稱更改,我的SiUserDetailsS​​ervice仍然可以工作,因為我沒有使用耳朵名稱進行查找。

我的Spring Security上下文文件仍然是:

<beans:bean id = "siUserDetailsService" class = "com.xxx.xxx.beans.SiUserDetailsService" />  

    <authentication-manager>
        <authentication-provider user-service-ref="siUserDetailsService">
        </authentication-provider>
    </authentication-manager>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM