1

I am using RolesAllowedDynamicFeature as defined in https://jersey.java.net/documentation/latest/security.html#annotation-based-security example 16.5 and 16.6

I register it as this:

@ApplicationPath("/demo")
public class App extends ResourceConfig {
    public App() {
        this.packages("com.bla bla bla package");
        register(RolesAllowedDynamicFeature.class);
    }
}

And then in the Java class I do this:

@Path("request")
@RolesAllowed({ "admin", "thirdPartyDeveloper" })
public class DemoService {
}

My question is where to state the users who belong to the admin role and the users who belong to the third party developer role?

Where can I set their credentials?

Geeky Guy
  • 9,229
  • 4
  • 42
  • 62
Marco Dinatsoli
  • 10,322
  • 37
  • 139
  • 253
  • It use the Interface SecurityContext to find user / role, so you can find implementation in a Java EE server or in Spring Security (http://docs.spring.io/spring-security/site/docs/current/guides/html5/) – Mr_Thorynque Sep 05 '16 at 13:03
  • 1
    Thank you but I am not using Spring – Marco Dinatsoli Sep 05 '16 at 13:52
  • Ok what application server you used ? If it's a Java EE server you'll find in it's documentation how to configure securityContext. If tomcat I think you need to find a external implementation (maybe spring security or http://picketbox.jboss.org). – Mr_Thorynque Sep 05 '16 at 13:53
  • @Mr_Thorynque that is the thing, the security context, but where/and how should I define it. from this page https://jersey.java.net/documentation/latest/security.html#annotation-based-security i can see there is `getSecurityContext()` function, I tried to call it from my `App ` class, but there is no such a method. could you help please ? – Marco Dinatsoli Sep 05 '16 at 13:55
  • It is explained in chapiter 16.1.1.1. Initializing Security Context with Servlets, it is the servlet container that give the securitycontext, so you need to configure user/profile in the server. This feature is include in Java EE server, but I don't think that is include in tomcat. – Mr_Thorynque Sep 05 '16 at 14:11
  • Java EE exemple : http://www.butonic.de/2010/06/18/a-simple-jax-rs-security-context-example-in-glassfish/ – Mr_Thorynque Sep 05 '16 at 14:12

1 Answers1

2

It depends on how your authentication mechanism looks like.

Java EE Security

If you are relying on the standard Java EE Web application security mechanisms offered by the servlet container, the authentication can be configured via the application's web.xml descriptor. It's very likely you will need to define a realm in your container and reference it in your web.xml descriptor with the <real-name> element. Something like:

<security-constraint>
    <web-resource-collection>
        <url-pattern>/rest/admin/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>admin</role-name>
    </auth-constraint>
</security-constraint>
<security-constraint>
    <web-resource-collection>
        <url-pattern>/rest/orders/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>customer</role-name>
    </auth-constraint>
</security-constraint>
<login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>my-default-realm</realm-name>
</login-config>

In this approach, your realm will tell the container whether a user is in a role or not.

To learn more about Java EE Security, have a look at the Java EE Tutorial.

Custom authentication

On the other hand, when you are performing a custom authentication like the one described in this answer, you could use a custom implementation of SecurityContext. In this situation, you need to authenticate the user manually against your LDAP, database, file, etc.

For a custom authetication, you could use a ContainerRequestFilter like the one show below:

@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {

        // Authenticate the user: How the authentications will be performed is up to you
        // If the authentication failed, abort the request with a 401 status code
        // If the authentication succeeded, you know who your user claims to be

        final SecurityContext securityContext = requestContext.getSecurityContext();
        requestContext.setSecurityContext(new SecurityContext() {

            @Override
            public Principal getUserPrincipal() {
                 return new Principal() {
                    @Override
                    public String getName() {
                        // Return the user name here
                        return null;
                    }
                };
            }

            @Override
            public boolean isUserInRole(String role) {
                // Return if the user is in a role
                return true;
            }

            @Override
            public boolean isSecure() {
                return securityContext.isSecure();
            }

            @Override
            public String getAuthenticationScheme() {
                return "Custom";
            }
        });
    }
}

How the authentication will be performed is your business. The recommended approach for HTTP authetication is to send the credentials in the Authorization header of the request. The ContainerRequestContext API will give you access to details of the request.

In this approach, you need to write the code to determine whether a user is in a role or not.


Note: Mind that you won't rely on sessions. The authentication/authorization process must be performed for each request.

Community
  • 1
  • 1
cassiomolin
  • 124,154
  • 35
  • 280
  • 359
  • I am using basic http authentication, in your public String getName() function, where is the name comes from ? is it the user name the user has send? or what? – Marco Dinatsoli Sep 05 '16 at 14:19
  • @MarcoDinatsoli How do you authenticate the users? Show the code. – cassiomolin Sep 05 '16 at 14:22
  • @MarcoDinatsoli I suppose you let the server manage authentication for you, without code. I think you can implement SecurityContext using HttpServletRequest. – Mr_Thorynque Sep 05 '16 at 15:19
  • @CássioMazzochiMolin thanks but please where can I state that **the user name marco** is **admin** role, sounds like my english is so bad that no one is understanding me – Marco Dinatsoli Sep 05 '16 at 16:48
  • @MarcoDinatsoli It could be stated in the database, in a file, hard coded... Do you use Java EE Security or what? – cassiomolin Sep 05 '16 at 16:57
  • @CássioMazzochiMolin okay so whenever any request comes to my server, the code in the AuthenticationFilter will be executed ? right? (appreciate it ) – Marco Dinatsoli Sep 05 '16 at 16:58
  • @MarcoDinatsoli Yes, the filter will be executed for each request that comes to the server. – cassiomolin Sep 05 '16 at 18:02
  • @CássioMazzochiMolin thanks, I put System.out.println("role=" + role); in the isUserInRole function, and nothing was printed, means that function is not being called, though i have this @RolesAllowed({ "admin", "thirdPartyDeveloper" }) in the beginning of my class that has my services. Note that the *filter* is being called, i can see that, could you help please? – Marco Dinatsoli Sep 05 '16 at 22:42
  • plus, my friend, you said that i get the username from the database or a file or or or ... but the username is coming in the request, i need to know that username to know if i authenticate it or not, please how can I get that username from the request? your code returns "null" in the method for user name, should I user that *requestContext* instance to extract the username from the headers? – Marco Dinatsoli Sep 05 '16 at 22:57