首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JAAS - Java EE 6中的Java编程安全性(没有@DeclareRoles)

JAAS - Java EE 6中的Java编程安全性(没有@DeclareRoles)
EN

Stack Overflow用户
提问于 2012-10-26 09:43:36
回答 2查看 5.1K关注 0票数 9

Java安全性是我过去几周的主要主题,我归档如下:

  • 自定义阀门验证器(extends AuthenticatorBase)
  • jBoss的自定义登录模块(extends UsernamePasswordLoginModule)
  • 安全端点(JAX-RS)

我的主要问题是,我的端点只适用于注释@DeclareRoles,如果我不使用它,就无法通过身份验证。详细地说,方法AuthenticatorBase.invoke (来自org.apache.catalina.authenticator)调用方法RealmBase.hasResourcePermission,并在那里检查角色。

因为我不使用任何预定义的角色,所以检查将失败。

我的问题是:有没有办法使用这样的代码:

代码语言:javascript
复制
@Path("/secure")
@Stateless
public class SecuredRestEndpoint {  

    @Resource
    SessionContext ctx;

    @GET
    public Response performLogging() {

        // Receive user information
        Principal callerPrincipal = ctx.getCallerPrincipal();
        String userId = callerPrincipal.getName();

        if (ctx.isCallerInRole("ADMIN")) {
            // return 200 if ok
            return Response.status(Status.OK).entity(userId).build();
        }
    ...
    }
}

一些额外的背景:需要使用反向代理进行身份验证,只要用户名被转发(X转发用户)。这就是为什么我使用自己的身份验证类和自定义登录模块(我没有任何密码凭据)。但是我认为这个问题也发生在来自应用服务器本身的标准身份验证方法上。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-11-01 04:04:54

由于您的代码是静态的(意味着您有一组可以被保护的静态资源),除了增加访问粒度之外,我不理解您添加安全角色的需求。我可以在模块化环境中看到这种需求,在这种环境中,代码不是静态的,在这种情况下,您需要支持后面的部署所声明的额外的安全角色。

尽管如此,我必须实现类似的东西,一个支持以下功能的安全系统:

  • 在不重新部署的情况下添加(声明)/删除角色;
  • 将用户与这些角色相关联。

我将在高度抽象的基础上描述我所做的事情,并希望它能给您提供一些有用的想法。

首先,实现一个@EJB,如下所示:

代码语言:javascript
复制
@Singleton
@LocalBean
public class MySecurityDataManager {

    public void declareRole(String roleName) {
        ...
    }

    public void removeRole(String roleName) {
        ...
    }

    /**
     * Here, I do not know what your incoming user data looks like such as:
     * do they have groups, attributes? In my case I could determine user's groups
     * and then assign them to roles based on those. You may have some sort of
     * other attribute or just plain username to security role association.
     */
    public void associate(Object userAttribute, String roleName) {
        ...
    }

    public void disassociate(Object userAttribute, String roleName) {
        ...
    }

    /**
     * Here basically you inspect whatever persistence method you chose and examine
     * your existing associations to build a set of assigned security roles for a
     * user based on the given attribute(s).
     */
    public Set<String> determineSecurityRoles(Object userAttribute) {
        ...
    }
}

然后实现一个自定义javax.security.auth.spi.LoginModule。我建议从无到有地实现它,除非您知道容器提供的抽象实现将对您有效,而对我则不然。此外,我建议你熟悉以下内容,如果你不熟悉,以更好地理解我要做的事情:

  • Modules.html
  • http://docs.oracle.com/javase/7/docs/api/javax/security/auth/spi/LoginModule.html
  • http://docs.oracle.com/javase/7/docs/api/java/security/acl/Group.html

代码语言:javascript
复制
public class MyLoginModule implements LoginModule {

    private MySecurityDataManager srm;

    @Override
    public void initialize(Subject subject, CallbackHandler callbackHandler,
            Map<String, ?> sharedState, Map<String, ?> options) {
        // make sure to save subject, callbackHandler, etc.
        try {
            InitialContext ctx = new InitialContext();
            this.srm = (MySecurityDataManager) ctx.lookup("java:global/${your specific module names go here}/MySecurityDataManager");
        } catch (NamingException e) {
            // error logic
        }
    }

    @Override
    public boolean login() throws LoginException {
        // authenticate your user, see links above
    }

    @Override
    public boolean commit() throws LoginException {
        // here is where user roles get assigned to the subject
        Object userAttribute = yourLogicMethod();
        Set<String> roles = srm.determineSecurityRoles(userAttribute);
        // implement this, it's easy, just make sure to include proper equals() and hashCode(), or just use the Jboss provided implementation.
        Group rolesGroup = new SimpleGroup("Roles", roles);
        // assuming you saved the subject
        this.subject.getPrincipals().add(rolesGroup);
    }

    @Override
    public boolean abort() throws LoginException {
        // see links above
    }

    @Override
    public boolean logout() throws LoginException {
        // see links above
    }

}

为了允许动态配置(即声明角色、关联用户),构建一个UI,该UI使用相同的@EJB MySecurityDataManager来CRUD您的安全设置,登录模块将使用这些设置来确定安全角色。

现在,您可以以您想要的方式打包这些文件,只需确保MyLoginModule能够查找MySecurityDataManager并将它们部署到容器中。我在JBoss上工作,您提到了JBoss,所以这也适用于您。一个更健壮的实现将包括LoginModule配置中的查找字符串,然后您可以在运行时从initialize()方法中的选项映射中读取该字符串。下面是JBoss的一个示例配置:

代码语言:javascript
复制
<security-domain name="mydomain" cache-type="default">
    <authentication>
        <login-module flag="required"
                      code="my.package.MyLoginModule"
                      module="deployment.${your deployment specific info goes here}">
            <module-option name="my.package.MySecurityDataManager"
                           value="java:global/${your deployment specific info goes here}/MySecurityDataManager"/>
        </login-module>
    </authentication>
</security-domain>

此时,您可以使用这个安全域mydomain来管理容器中任何其他部署的安全性。

下面是几种使用场景:

  1. 部署一个新的.war并将其分配给mydomain安全域。.war在其整个代码中都附带了预定义的安全注释。您的安全领域最初没有它们,因此没有用户可以登录。但是在部署之后,由于安全角色已经有了详细的文档记录,所以您可以打开您编写的mydomain配置接口,并声明这些角色,然后将用户分配给它们。现在他们可以登录了。
  2. 经过几个月的部署,您不再希望用户能够访问特定的战争标准。从您的.war中删除与该部分mydomain相关的安全角色,没有人能够使用它。

最好的部分,特别是关于#2是没有重新部署。此外,没有编辑XML来覆盖用注释声明的默认安全设置(假设您的接口比注释更好)。

干杯!我很乐意提供更多的细节,但就目前而言,这至少应该告诉您是否需要它们。

票数 7
EN

Stack Overflow用户

发布于 2012-10-29 16:05:03

如果我把你说对了,有两个问题。

  1. 您不希望@DeclareRoles出现在您的代码中。如果您不介意使用web.xml,请看以下内容:http://docs.oracle.com/cd/E19159-01/819-3669/bncbg/index.html
  2. 您只想使用用户名访问rest资源,因为rest资源不存在安全威胁,但同时rest资源需要知道调用的是谁。

代码语言:javascript
复制
1. There is more than one way to do this. For identifying the user, you only need to provide user's id in your http request, `JAAS` security is overkill. For example, provide userid by `URI:/user/bob`, or by URI parameters like: `/user?id=bob`. 
2. If security is mandatory (if I don't get it wrong, you are using javaee's standard security component), you'll need to deal with roles, because `java6`'s specification have role-based authentication/authorization written in.

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13084517

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档