动态添加Java EE安全角色,而不使用部署描述符 [英] Add Java EE Security Roles dynamically without using deployment descriptor

查看:100
本文介绍了动态添加Java EE安全角色,而不使用部署描述符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Glassfish 3.1,B06开发Java EE 6应用程序。
为了保护我的应用程序,我使用JDBCRealm和编程安全。检查用户名和密码是否正常。但是在声明安全角色时,我有一个问题:



要在Java EE 6中使用安全角色,我必须在EJB部署描述符中声明这些角色并在Glassfish特定的部署描述符中链接这些角色(如 Java EE 6教程
只有我可以使用EJB中的方法 isCallerInRole(String roleRef)来检查权限。 p>

对于我的应用程序来说,这是不可取的,因为我希望可以动态和编程地添加安全角色,而无需编写XML文件(例如,在数据库中定义角色名称)。



我刚刚通过GF3源代码调试,并在 com.sun.ejb.containers.EjbContextImpl 中看到了isCallerInRole的实现。容器从EJB描述符中获取角色:

  public boolean isCallerInRole(String roleRef){
(。 ..)
EjbDescriptor ejbd = container.getEjbDescriptor();
RoleReference rr = ejbd.getRoleReferenceByName(roleRef);
(...)
}

我环顾四周,发现如果我可以以某种方式在我的应用程序中获取EJB描述符,我可以添加一个这样的角色:

  EjbDescriptor ejbd = //? ??我可以在我的应用程序中使用该描述符,还是禁止? 
RoleReference rr = new RoleReference(admin,Admins are allowed to do everything);
ejbd.addRoleReference(rr);

有人做了这样的事情,还是有一些想法?可以在我的应用程序中使用Ejb部署描述符吗?还是有更好的方法?



还是应该使用MBean来添加角色?找到一个相当相关的帖子 here

解决方案

我提出了以下解决方案,在登录后以编程方式添加角色,至少在GlassFish 3.1.2 build 23上起作用。 >

  import com.sun.enterprise.security.SecurityContext; 
import com.sun.enterprise.security.web.integration.PrincipalGroupFactory;
import java.security.Principal;
import java.util.Set;
import javax.security.auth.Subject;
import org.glassfish.security.common.Group;

public class GlassFishUtils {
public static void addGroupToCurrentUser(String groupName,String realmName){
Subject subject = SecurityContext.getCurrent()。getSubject();
设置< Principal> principals = subject.getPrincipals();
组组= PrincipalGroupFactory.getGroupInstance(groupName,realmName);
if(!principals.contains(group))
principals.add(group);
}
}

您需要添加从GlassFish到您的项目库的security.jar common-util.jar



不要忘了在您的web.xml中为要添加的角色创建一个< security-role> 部分。



请注意,我使用的功能似乎不是发布的稳定API的一部分,因此不保证在将来的GlassFish版本中继续使用。



我获得了有关如何从GlassFish的 sun.appserv.security.AppservPasswordLoginModule.commit()的源代码添加角色的信息。
如果将来的GlassFish版本破坏了我的代码,这个功能将是一个很好的开始,以便找出如何解决它。


I'm developing a Java EE 6 application using Glassfish 3.1, B06. To secure my app, i'm using a JDBCRealm and programmatic security. This works fine to check username and password. But when it comes to declaring security roles, i have a problem:

To use Security Roles in Java EE 6, i have to declare those roles both in the EJB deployment descriptor and in the Glassfish-specific deployment descriptor to link those roles (as explained in the Java EE 6-tutorial) Only than i can use the method isCallerInRole(String roleRef) inside an EJB to check permissions.

This is not desirable for my application, as i want that its possible to add Security roles both dynamically and programmatically, without having to write XML files (and for example make it possible to define role names in a database).

I just debugged through the GF3-source code and saw the implementation of isCallerInRole in com.sun.ejb.containers.EjbContextImpl. There the container gets the roles out of the EJB descriptor:

public boolean isCallerInRole(String roleRef) {
  (...)
  EjbDescriptor ejbd = container.getEjbDescriptor();
  RoleReference rr = ejbd.getRoleReferenceByName(roleRef);
  (...)
}

I looked around and found out that if i could somehow get the EJB descriptor inside my application, i could add a role like this:

EjbDescriptor ejbd = //??? Can i use that descriptor inside my app, or is that "forbidden"?
RoleReference rr = new RoleReference("admin", "Admins are allowed to do everything");
ejbd.addRoleReference(rr);

Anyone did something like this, or got some thoughts about it? Is it possible to use the Ejb deployment descriptor inside my application? Or are there better approaches?

P.S. or should i use MBeans to add Roles? Found a quite related post here.

解决方案

I came up with the following solution to add roles programmatically after login, which works at least on GlassFish 3.1.2 build 23.

import com.sun.enterprise.security.SecurityContext;
import com.sun.enterprise.security.web.integration.PrincipalGroupFactory;
import java.security.Principal;
import java.util.Set;
import javax.security.auth.Subject;
import org.glassfish.security.common.Group;

public class GlassFishUtils {
    public static void addGroupToCurrentUser(String groupName, String realmName) {
        Subject subject = SecurityContext.getCurrent().getSubject();
        Set<Principal> principals = subject.getPrincipals();
        Group group = PrincipalGroupFactory.getGroupInstance(groupName, realmName);
        if (!principals.contains(group))
            principals.add(group);
    }
}

You will need to add security.jar and common-util.jar from GlassFish to your project libraries.

And don't forget to create a <security-role> section in your web.xml for the roles you wish to add.

Note that I am using functionality which does not appear to be part of a published stable API, so there is no guarantee that this will keep working in future releases of GlassFish.

I got the information on how to add roles from the source code of sun.appserv.security.AppservPasswordLoginModule.commit() of GlassFish. If a future GlassFish release breaks my code, this function would be a good place to start in order to find out how to fix it.

这篇关于动态添加Java EE安全角色,而不使用部署描述符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆