简体   繁体   English

在JAVA EE6 Webservice中设置安全性

[英]Setting up security in JAVA EE6 Webservice

I am currently researching how Java EE6 Security can secure our applications using GlassFish. 我目前正在研究Java EE6 Security如何使用GlassFish保护我们的应用程序。 I know how to make realms, roles and users. 我知道如何制作领域,角色和用户。 I managed to get a nice basic login with a servlet. 我设法通过servlet获得了一个很好的基本登录。 'Normal'users were not allowed to see an admin page, while an admin user was, so that test worked out nicely. '普通'用户不允许看管理员页面,而管理员用户则是,所以测试很好。

Now however, I want to step a little bit deeper into it. 然而,现在,我想更深入一点。

The idea is that I host a webservice using an EJB container. 我的想法是使用EJB容器托管Web服务。 This webservice does not know anything about it's callers so I figured the caller has to send credentials (username and password) along with the call. 这个web服务对它的呼叫者一无所知,所以我认为呼叫者必须发送凭证(用户名和密码)以及呼叫。 The webservice could then authenticate the user and could then, based on this, allow or deny access to methods. 然后,webservice可以对用户进行身份验证,然后可以基于此允许或拒绝对方法的访问。

The thing is, that I have no clue on how to check 2 strings (username and password) and set up a role for the callers within the webservice. 问题是,我不知道如何检查2个字符串(用户名和密码)并为webservice中的调用者设置角色。

I know this API should help me out: http://docs.oracle.com/javaee/1.4/api/javax/ejb/EJBContext.html 我知道这个API可以帮助我: http//docs.oracle.com/javaee/1.4/api/javax/ejb/EJBContext.html

But it doesn't give me a clear understanding on how to do this. 但它并没有让我清楚地了解如何做到这一点。 All it says to me is that I can check certain properties when the user is already in a role, but since it's a webservice, there is no role yet... I have to create it first, but how? 它告诉我的是,当用户已经在某个角色时我可以检查某些属性,但由于它是一个web服务,所以还没有任何角色......我必须先创建它,但是如何?

Also, I know that GlassFish supports sign on through LDAP, which is the end goal I am working towards. 此外,我知道GlassFish支持通过LDAP登录,这是我正在努力的最终目标。 Perhaps any ideas on how to do that correctly? 也许关于如何正确地做到这一点的任何想法? What would be the best way to approach this all? 什么是最好的方法来解决这个问题?

Thanks in advance, 提前致谢,

Rens 伦斯

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

UPDATE/EDIT: UPDATE /编辑:

Alright, since I could only comment, and couldn't reply, I figured I'd just edit my original post. 好吧,因为我只能评论,而且无法回复,我想我只是编辑我原来的帖子。 Here we go: 开始了:

The idea is that I have to research Glassfish's EE6 Security for Webservices. 我的想法是我必须研究Glassfish的EE6 Security for Webservices。 Now... I read a lot about JAAS (Java Authetication Authorization Service). 现在......我读了很多关于JAAS(Java认证授权服务)的文章。 It works with annotations in the webservice bean like this: 它适用于webservice bean中的注释,如下所示:

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

I tried some stuff with a servlet, and that worked really great!! 我用servlet尝试了一些东西,这真的很棒! I have a basic authentication, which allowed the user to log in before accessing a webservice bean. 我有一个基本的身份验证,允许用户在访问webservice bean之前登录。 The servlet web.xml took care of the setting as in describing which realm to check and which users were there etc. servlet web.xml负责设置,如描述要检查的领域以及哪些用户在那里等。

Now, I have to test it without a servlet though, because the idea is that the webservice is able to run without it knowing it's clients. 现在,我必须在没有servlet的情况下测试它,因为我的想法是webservice能够在不知道它的客户端的情况下运行。 So a client should provide username and password along with his call. 所以客户端应该提供用户名和密码以及他的电话。 I used an interceptor to do the login, and then checking if the user is authorized to acces the method using the @RolesALlowed annotation. 我使用拦截器进行登录,然后检查用户是否有权使用@RolesALlowed注释访问该方法。

This is the code: the webservice bean: 这是代码: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";
    }

    }

Then the interceptor: 然后是拦截器:

@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();
    }

}
}

Now this works fine if I comment the @RolesAllowed("ADMIN"), except that every user I configured in the 'Developingjava' realm can use that method. 现在这可以正常工作,如果我评论@RolesAllowed(“ADMIN”),除了我在'Developingjava'领域配置的每个用户都可以使用该方法。 But if I use the @RolesAllowed("ADMIN"), I get the following error: 但是如果我使用@RolesAllowed(“ADMIN”),我会收到以下错误:

INFO: JACC Policy Provider: Failed Permission Check, context(EE6SecurityEAR/EE6SecurityEJB_jar)- permission((javax.security.jacc.EJBMethodPermission EE6SecurityBean testWaarde,ServiceEndpoint,java.lang.String,java.lang.String)) 信息:JACC策略提供程序:失败的权限检查,上下文(EE6SecurityEAR / EE6SecurityEJB_jar) - 权限((javax.security.jacc.EJBMethodPermission EE6SecurityBean testWaarde,ServiceEndpoint,java.lang.String,java.lang.String))

I have configured my sun-ejb-jar.xml like this (The servlet needed xml configuration, but I highly doubt the bean is even using it..): 我已经像这样配置了我的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>

I really need help on this. 我真的需要帮助。 Perhaps this is not the right way to deal with security for webservices at all, but my company wants me to do a research on new technology security of EE6... 也许这根本不是处理网络服务安全的正确方法,但我的公司希望我对EE6的新技术安全性进行研究......

Any advice? 有什么建议?

Thanks in advance :) 提前致谢 :)

The best way i'd suggest is to use 2-way SSL. 我建议的最好方法是使用双向SSL。 here is the method on how to setup 2-way ssl in glassfish . 这是关于如何在glassfish中设置双向ssl的方法 with 2-way ssl, the client (who is calling your service) should hold a jks (keystore) and the password. 对于双向ssl,客户端(正在调用您的服务)应该持有jks(密钥库)和密码。 this would identify the client with the server. 这将通过服务器识别客户端。 this way the authentication is done by the server and you don't need to code anything... 这样,身份验证由服务器完成,您无需编写任何代码......

this technique only works to identify 1 type of client (meaning you can't have any distinctions made from a user to an admin). 此技术仅用于识别1种类型的客户端(这意味着您不能对用户和管理员进行任何区分)。

If you are trying to identify callers (client) separately, then you can use wsse, security header, here you can provide each type of user with a user id and password, this info the user needs to pass in the soap header with each request. 如果您尝试单独识别呼叫者(客户端),那么您可以使用wsse,安全头,在这里您可以为每种类型的用户提供用户ID和密码,用户需要在每个请求的soap头中传递此信息。

This way you can identify and authenticate different users. 这样,您可以识别和验证不同的用户。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM