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

标签 java security jakarta-ee glassfish

我目前正在研究 Java EE6 安全性如何使用 GlassFish 保护我们的应用程序。我知道如何创建领域、角色和用户。 我设法使用 servlet 获得了一个很好的基本登录。 “普通”用户不允许查看管理页面,而管理员用户则可以, 所以测试很顺利。

不过现在,我想更深入地了解一下。

我的想法是,我使用 EJB 容器托管 Web 服务。 该网络服务对其调用者一无所知,因此我认为调用者必须随调用一起发送凭据(用户名和密码)。 然后,网络服务可以对用户进行身份验证,然后可以基于此来允许或拒绝对方法的访问。

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

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

但它并没有让我清楚地了解如何做到这一点。它对我说的是,当用户已经担任角色时,我可以检查某些属性, 但是因为它是一个网络服务,所以还没有角色......我必须先创建它,但是如何?

此外,我知道 GlassFish 支持通过 LDAP 登录,这是我努力实现的最终目标。也许关于如何正确执行此操作的任何想法? 处理这一切的最佳方法是什么?

提前致谢

伦斯

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

更新/编辑:

好吧,既然我只能评论,不能回复,我想我只能编辑我原来的帖子了。我们开始吧:

我的想法是我必须研究 Glassfish 的 Web 服务 EE6 安全性。 现在...我阅读了很多有关 JAAS(Java 身份验证授权服务)的内容。它与 web 服务 bean 中的注释一起工作,如下所示:

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

我用 servlet 尝试了一些东西,效果非常好!!我有一个基本身份验证,它允许用户在访问 web 服务 bean 之前登录。 servlet web.xml 负责设置,如描述要检查的领域以及那里有哪些用户等。

现在,我必须在没有 servlet 的情况下测试它,因为这个想法是 web 服务能够在不知道它的客户端的情况下运行。因此,客户应在调用时提供用户名和密码。我使用拦截器进行登录,然后检查用户是否有权使用 @RolesALlowed 注释访问该方法。

这是代码: 网络服务 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>

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

有什么建议吗?

提前致谢:)

最佳答案

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

此技术仅适用于识别一种类型的客户端(这意味着您无法区分用户和管理员)。

如果你想单独识别调用者(客户端),那么你可以使用wsse,security header,在这里你可以为每种类型的用户提供一个用户id和密码,这个信息用户需要在soap header中传递每个请求。

这样您就可以识别和验证不同的用户。

关于java - 在 JAVA EE 6 Web 服务中设置安全性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8429935/

相关文章:

security - HBase错误禁用安全特性不可用

.net - Microsoft安全通报(2269637)对.NET编码的影响

python - Django 管理表单可以使用跨站请求伪造 (CSRF) 进行操作

java Restful Web 应用程序和 WADL

java.lang.NoClassDefFoundError : Could not initialize class com. ibm.mq.jms.MQQueueConnectionFactory 错误

java - 将 string.xml 中的值从一个 Activity 传递到另一个 Activity ?

java - Java derby 数据库上的数据库备份

java - 如何解析来自网站的自定义 XML 样式错误代码响应