[英]@EJB injection in a Custom UserdetailsService (implementing Spring Security UserDetailsService)
我在應用程序的JPA / EJB 3 / JSF 2 / Spring Security 3中使用glassfish 3.1.2。 我想編寫一個像這樣的自定義UserdetailsService:
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;
}
}
所以我試圖在我的MyUserDetailsService中注入一個EJB,以便能夠在我的Spring Security上下文文件:“ applicationContext-security.xml”中將它用作身份驗證提供者:
<authentication-manager>
<authentication-provider user-service-ref="myUserDetailsService">
</authentication-provider>
</authentication-manager>
問題是,我陷入了由null的合作商身份導致的NullPointerException。
我嘗試了幾件事,其中包括:
Loooking了使用上下文(如一個選址的EJB 這里 ):解決方案的工作,但是這不是我想要的:因為EJB的名字是受到修改。
將類MyUserDetailsService放置為JSF 2托管Bean時,collaborateFacade一直保持為空。
將類MyUserDetailsService放置為JSF 2受管bean並具有ApplicationScoped范圍,collaborateFacade一直保持為空。
問題:是否有任何干凈的方法將EJB注入MyUserDetailsService類中?
我知道我可以使用@Service注釋對類進行注釋(請參閱此鏈接 ),然后我會陷入EJB和Spring的混合使用,這是我不想要的
這是一個簡單的例子, 理論上應該可以工作
<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。 然后我的UserDetailsService變成這樣:
@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 =
這條路:
我的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.