我得到Interceptors
在应用服务器上工作。我有注释EJB:
@Stateless
@Named("accountsEJB")
public class AccountsEJB {
@PersistenceContext(unitName = "weducationPU")
private EntityManager em;
// . . . other methods
@WithLog
@Restricted(allowedRoles = {}) // Allowed only for admin
public Account save(Account item) {
if (item.getId() == 0) {
em.persist(item);
return item;
} else {
return em.merge(item);
}
}
@WithLog
@Restricted(allowedRoles = {}) // Allowed only for admin
public void delete(final Account item) {
Account a = em.find(Account.class, item.getId());
if (null != a) {
em.remove(a);
}
}
}
空角色列表表示仅允许角色admin
。
此EJB的单元测试文件
public class AccountsEJBTest {
private static EJBContainer container;
private static AccountsEJB ejb;
@BeforeClass
public static void setUpClass() {
try {
Map<String, Object> properties = new HashMap<>();
properties.put(EJBContainer.MODULES, new File("target/classes"));
properties.put("org.glassfish.ejb.embedded.glassfish.installation.root", "glassfish");
properties.put(EJBContainer.APP_NAME, "weducation");
container = EJBContainer.createEJBContainer(properties);
ejb = (AccountsEJB) container.getContext().lookup("java:global/weducation/classes/AccountsEJB");
System.out.println("AccountsEJBTest running...");
} catch (NamingException e) {
fail("Container init error: " + e.getMessage());
}
}
@AfterClass
public static void tearDownClass() {
if (null != container) {
container.close();
}
System.out.println("AccountsEJBTest finished");
}
private boolean equals(Account source, Account result) {
if (!source.getFullName().contentEquals(result.getFullName())) return false;
if (!source.getLogin().contentEquals(result.getLogin())) return false;
return source.getRole() == result.getRole();
}
@Test
public void testOperations() {
try {
System.out.println("-->testOperations()");
Account testAccount = new Account();
testAccount.setFullName("Test Account");
testAccount.setLogin("test");
testAccount.setPassword("test");
testAccount.setConfirm("test");
testAccount.updatePassword();
testAccount.setRole(AccountRole.DEPOT);
Account savedAccount = ejb.save(testAccount);
assertTrue(equals(testAccount, savedAccount));
savedAccount.setFullName("Still Test Account");
savedAccount.setLogin("test1");
testAccount = ejb.save(savedAccount);
assertTrue(equals(testAccount, savedAccount));
testAccount.setPassword("testpwd");
testAccount.setConfirm("testpwd");
testAccount.updatePassword();
savedAccount = ejb.save(testAccount);
assertTrue(equals(testAccount, savedAccount));
ejb.delete(savedAccount);
} catch (Exception e) {
fail("Exception class " + e.getClass().getName() + " with message " + e.getMessage());
}
}
}
这个测试工作。我认为,这是不正确的,因为没有登录管理员角色的用户。但为什么这种行为会受到影响呢?
更新。
@Restricted interface:
@Inherited
@InterceptorBinding
@Target({METHOD, TYPE})
@Retention(RUNTIME)
public @interface Restricted {
@Nonbinding
AccountRole[] allowedRoles();
}
SecurityInterceptor类
@Interceptor
@Restricted(allowedRoles = {})
public class SecurityInterceptor implements Serializable {
@Inject
private transient SessionMB session;
@AroundInvoke
public Object checkSecurity(InvocationContext context) throws Exception {
//System.out.println("Security checker started.");
if ((session == null) || (session.getUser() == null)) {
throw new SecurityException("Can't get user info");
}
// Allow all to admin
if (session.isAdmin()) {
//System.out.println("It's admin.");
return context.proceed();
}
// walk non administrator roles
for (AccountRole r : getAllowedRoles(context.getMethod())) {
// if match - accept method invocation
if (session.getUser().getRole() == r) {
//System.out.println("It's " + r.getDescription());
return context.proceed();
}
}
throw new SecurityException(session.getUser().getFullName()
+ " has no souch privilegies ");
}
private AccountRole[] getAllowedRoles(Method m) {
if (null == m) {
throw new IllegalArgumentException("Method is null!");
}
// Walk all method annotations
for (Annotation a : m.getAnnotations()) {
if (a instanceof Restricted) {
return ((Restricted) a).allowedRoles();
}
}
// Now - walk all class annotations
if (null != m.getDeclaringClass()) {
for (Annotation a : m.getDeclaringClass().getAnnotations()) {
if (a instanceof Restricted) {
return ((Restricted) a).allowedRoles();
}
}
}
// if no annotaion found
throw new RuntimeException("Annotation @Restricted not found at method "
+ m.getName() + " or it's class.");
}
}
beans.xml
位于WEB-INF
文件夹中,看起来像
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="annotated">
<interceptors>
<class>ru.edu.pgtk.weducation.interceptors.LogInterceptor</class>
<class>ru.edu.pgtk.weducation.interceptors.SecurityInterceptor</class>
</interceptors>
</beans>
有人可以帮助我知道:
感谢您的时间和问题。