简体   繁体   中英

Setting up security in JAVA EE6 Webservice

I am currently researching how Java EE6 Security can secure our applications using GlassFish. I know how to make realms, roles and users. I managed to get a nice basic login with a 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. 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. The webservice could then authenticate the user and could then, based on this, allow or deny access to methods.

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.

I know this API should help me out: 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?

Also, I know that GlassFish supports sign on through LDAP, which is the end goal I am working towards. 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:

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. Now... I read a lot about JAAS (Java Authetication Authorization Service). It works with annotations in the webservice bean like this:

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

I tried some stuff with a servlet, and that worked really great!! I have a basic authentication, which allowed the user to log in before accessing a webservice bean. The servlet web.xml took care of the setting as in describing which realm to check and which users were there etc.

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. 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.

This is the code: the 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. But if I use the @RolesAllowed("ADMIN"), I get the following error:

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))

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..):

    <?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...

Any advice?

Thanks in advance :)

The best way i'd suggest is to use 2-way SSL. here is the method on how to setup 2-way ssl in glassfish . with 2-way ssl, the client (who is calling your service) should hold a jks (keystore) and the password. 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).

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.

This way you can identify and authenticate different users.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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