Deltaspike и @Stateless Bean
Я хочу защитить свой EJb без сохранения состояния с помощью DeltaSpike-API.
@Stateless
@Remote(UserServiceRemote.class)
public class UserService implements UserServiceRemote
На уровне метода у меня есть пользовательская аннотация "Поддержка"
@Support
public void doSomething() {}
Поэтому я написал пользовательскую аннотацию "@Support":
@Retention(value = RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD })
@Documented
@SecurityBindingType
public @interface Support {
Мой пользовательский Authorizer выглядит так:
@Secures
@Support
public boolean doAdminCheck(Identity identity, IdentityManager identityManager, RelationshipManager relationshipManager)
throws Exception {
return hasRole(relationshipManager, identity.getAccount(), getRole(identityManager, "Support"));
}
В моем файле "beans.xml" я включил:
<interceptors>
<class>org.apache.deltaspike.security.impl.extension.SecurityInterceptor</class>
</interceptors>
Но после того, как я вхожу в приложение и вызываю метод "doSomething" для каждого удаленного вызова, аннотация "Поддержка" игнорируется, независимо от того, есть ли у меня роль или нет.
Что я делаю не так? Спасибо за все предложения!
2 ответа
Ejb и CDI - это две разные концепции. Сессионный компонент без сохранения состояния и управляемый компонент CDI управляются разными контейнерами. Таким образом, вы не можете использовать Deltaspike для сессионного компонента без сохранения состояния. Если вы хотите использовать безопасность deltaspike, используйте взамен именованный компонент и используйте другую стратегию удаленного взаимодействия.
В моем случае я должен был убедиться, что модуль (jar), содержащий сервис, который я хотел защитить с помощью аннотации, содержал файл beans.xml с перехватчиком deltaspike (ранее я добавлял файл только в модуль с самим кодом безопасности, который был проблема).
Также я узнал, что мне нужно отделить службу бизнес-логики от самой декларации конечной точки SOAP. Эта пользовательская служба EJB @Stateles (или любая другая) может быть @Inject-ed в SOAP, и над ней будут работать аннотации безопасности (здесь @Support).
На мой взгляд, отделение объявления конечной точки от бизнес-кода в любом случае является хорошим дизайном, поскольку у нас может быть несколько интерфейсов, вызывающих одну и ту же бизнес-логику. (и проще для модульного тестирования и т. д.)
В зависимости от bean-discovery-mode, определенного в beans.xml, ваш UserService может быть недоступен из контейнера CDI. Вы должны использовать "аннотированный" режим обнаружения и аннотировать свой UserService с помощью Dependent.