在JAVA EE 6 Web服务中设置安全性

时间:2011-12-08 11:03:01

标签: java security java-ee glassfish

我目前正在研究Java EE6 Security如何使用GlassFish保护我们的应用程序。我知道如何制作领域,角色和用户。 我设法通过servlet获得了一个很好的基本登录。 '普通'用户不允许看到管理页面,而管理员用户是, 这样测试很好。

然而,现在,我想更深入一点。

我的想法是使用EJB容器托管Web服务。 这个web服务对它的呼叫者一无所知,所以我认为呼叫者必须发送凭证(用户名和密码)以及呼叫。 然后,webservice可以对用户进行身份验证,然后可以基于此允许或拒绝对方法的访问。

问题是,我不知道如何检查2个字符串(用户名和密码)并为网络服务中的呼叫者设置角色。

我知道这个API可以帮助我: http://docs.oracle.com/javaee/1.4/api/javax/ejb/EJBContext.html

但它并没有让我清楚地了解如何做到这一点。它告诉我的是,当用户已经在角色中时,我可以检查某些属性, 但由于它是一个网络服务,但还没有任何作用......我必须首先创建它,但是如何?

另外,我知道GlassFish支持通过LDAP登录,这是我正在努力的最终目标。也许关于如何正确地做到这一点的任何想法? 什么是最好的方法来解决这个问题?

提前致谢,

的Rens

=============================================== ==============================

UPDATE /编辑:

好吧,因为我只能评论,而且无法回复,我想我只是编辑我原来的帖子。我们走了:

我的想法是我必须研究Glassfish的EE6 Security for Webservices。 现在......我读了很多关于JAAS(Java认证授权服务)的文章。它适用于webservice bean中的注释,如下所示:

@RolesAllowed("ADMIN")
public String doAdminStuff(){
   // do something
}

我尝试了一些带有servlet的东西,这真的很棒!我有一个基本的身份验证,允许用户在访问webservice bean之前登录。 servlet web.xml负责设置,如描述要检查的领域以及哪些用户在那里等。

现在,我必须在没有servlet的情况下测试它,因为我们的想法是webservice能够在不知道它的客户端的情况下运行。所以客户端应该提供用户名和密码以及他的电话。我使用拦截器进行登录,然后检查用户是否有权使用@RolesALlowed注释访问该方法。

这是代码: webservice bean:

@LocalBean
    @WebService
    @Stateless
    public class EE6SecurityBean implements EE6SecurityBeanInterface {

    @Interceptors(UserValidationInterceptor.class)
    @RolesAllowed("ADMIN")
    public String doAdminStuff(String user, String password){
        return "it works";
    }

    }

然后是拦截器:

@Interceptor
    public class UserValidationInterceptor {

private ProgrammaticLoginInterface programmaticLogin = new ProgrammaticLogin();
@AroundInvoke
public Object intercept(InvocationContext ctx) throws Exception {

    // for all parameters
    List<String> list = new ArrayList<String>();
    for (Object p : ctx.getParameters()) {
        list.add(p.toString());
    }
    String username = list.get(0).toString();
    String password = list.get(1).toString();

    boolean loginSuccessful = programmaticLogin.login(
            username, password, "Developingjava", true);  
    if (loginSuccessful) {

    return ctx.proceed();
    }else{
        throw new userValidationException();
    }

}
}

现在,如果我评论@RolesAllowed(“ADMIN”),这可以正常工作,除了我在'Developingjava'领域配置的每个用户都可以使用该方法。但是如果我使用@RolesAllowed(“ADMIN”),我会收到以下错误:

信息:JACC策略提供程序:失败的权限检查,上下文(EE6SecurityEAR / EE6SecurityEJB_jar) - 允许((javax.security.jacc.EJBMethodPermission EE6SecurityBean testWaarde,ServiceEndpoint,java.lang.String中,java.lang.String中))

我已经像这样配置了我的sun-ejb-jar.xml(servlet需要xml配置,但我非常怀疑bean是否使用它...):

    <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 EJB 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-ejb-jar_3_0-0.dtd">
<sun-ejb-jar>


    <security-role-mapping>
        <role-name>ADMIN</role-name>
        <group-name>Admin</group-name>
        <principal-name>Admin</principal-name>
    </security-role-mapping>


        <enterprise-beans>
        <unique-id>1</unique-id>
        <ejb>
            <ejb-name>EE6SecurityBean</ejb-name>
            <jndi-name></jndi-name>

            <pass-by-reference>false</pass-by-reference>
            <ior-security-config>
                <transport-config>
                    <integrity>supported</integrity>
                    <confidentiality>supported</confidentiality>
                    <establish-trust-in-target>supported</establish-trust-in-target>
                    <establish-trust-in-client>supported</establish-trust-in-client>
                </transport-config>
                <as-context>
                    <auth-method>username_password</auth-method>
                    <realm>Developingjava</realm>
                    <required>true</required>
                </as-context>
                <sas-context>
                    <caller-propagation>supported</caller-propagation>
                </sas-context>
            </ior-security-config>
            <is-read-only-bean>false</is-read-only-bean>
            <refresh-period-in-seconds>-1</refresh-period-in-seconds>
            <gen-classes/>

        </ejb>
    </enterprise-beans>
</sun-ejb-jar>

我真的需要帮助。也许这根本不是处理网络服务安全的正确方法,但我的公司希望我对EE6的新技术安全性进行研究......

有什么建议吗?

提前致谢:)

1 个答案:

答案 0 :(得分:0)

我建议的最好方法是使用双向SSL。 这是method on how to setup 2-way ssl in glassfish。 对于双向ssl,客户端(正在调用您的服务)应该持有jks(密钥库)和密码。这将通过服务器识别客户端。 这样,身份验证由服务器完成,您无需编写任何代码......

此技术仅用于识别1种类型的客户端(意味着您不能对用户和管理员进行任何区分)。

如果您尝试单独识别呼叫者(客户端),那么您可以使用wsse,安全标头,在这里您可以为每种类型的用户提供用户ID和密码,用户需要在soap标头中传递此信息每个请求。

通过这种方式,您可以识别和验证不同的用户。