Java httpServer basic authentication for different request methods












10














I'm using a very simple httpServer in Java for an api rest with GET, POST, PUT and DELETE. I'm using Basic Authentication and I have a couple classes Authentication.java and Authorisation.java which I use to authenticate and check permissions for the users.



So, the thing is that I want all users (authenticated) to be able to GET information from my api rest, but only users with certain privileges to be able to POST, PUT and DELETE. So how can I do that?



This is what I got



public class Server {

private static HttpServer server;

public static void start() throws IOException {

server = HttpServer.create(new InetSocketAddress(8000), 0);
HttpContext ctx = server.createContext("/users", new UserHandler());
ctx.setAuthenticator(new ApiRestBasicAuthentication("users"));

server.start();
}

}


And this is my ApiRestBasicAuthentication



public class ApiRestBasicAuthentication extends BasicAuthenticator {

private UserAuthentication authentication = new UserAuthentication();

public ApiRestBasicAuthentication(String realm) {
super(realm);
}

@Override
public boolean checkCredentials(String user, String pwd) {
int authCode = authentication.authenticate(user, pwd);
return authCode == UserAuthentication.USER_AUTHENTICATED;
}

}


As this is now, check credentials is only checking if the user is authenticated.
But I'd like to check, if the method is POST, DELETE or PUT I should also check the specific credentials. But how can I get the method in my ApiRestBasicAuthentication? I'm doing that in my handler class



public void handle(HttpExchange httpExchange) throws IOException {
String method = httpExchange.getRequestMethod();
if ("post".equalsIgnoreCase(method)) {
createUser(httpExchange);
} else if ("get".equalsIgnoreCase(method)) {
readUsers(httpExchange);
} else if ("put".equalsIgnoreCase(method)) {
updateUser(httpExchange);
} else if ("delete".equalsIgnoreCase(method)) {
deleteUser(httpExchange);
}
}


Maybe this is supposed to be done some other way.
Any ideas?



Many thanks.










share|improve this question






















  • I suppose you'll need some authorisation aspect (or similiar functionality given by filter or interceptor) that will only respond to non-GETs if user is authorised, though I cannot help you right now with full answer. Figure out which of those (aspect, filter, interceptor) you have available and read about it.
    – Filip Malczak
    Dec 31 '16 at 11:16










  • That could work because I can check the method (POST, GET, PUT,...) in the filter, but then how can I get the username sent in the request inside the filter? My ApiRestBasicAuthentication has a checkCredentials() function which receives the user and password, but in the Filter I just have the httpExchange object, and the username/password is encripted.
    – David
    Dec 31 '16 at 17:31












  • I suggest you to use spring-security for that. Take a lookt at the following answer: stackoverflow.com/a/45965232/540286
    – Ortwin Angermeier
    Nov 9 '18 at 15:30
















10














I'm using a very simple httpServer in Java for an api rest with GET, POST, PUT and DELETE. I'm using Basic Authentication and I have a couple classes Authentication.java and Authorisation.java which I use to authenticate and check permissions for the users.



So, the thing is that I want all users (authenticated) to be able to GET information from my api rest, but only users with certain privileges to be able to POST, PUT and DELETE. So how can I do that?



This is what I got



public class Server {

private static HttpServer server;

public static void start() throws IOException {

server = HttpServer.create(new InetSocketAddress(8000), 0);
HttpContext ctx = server.createContext("/users", new UserHandler());
ctx.setAuthenticator(new ApiRestBasicAuthentication("users"));

server.start();
}

}


And this is my ApiRestBasicAuthentication



public class ApiRestBasicAuthentication extends BasicAuthenticator {

private UserAuthentication authentication = new UserAuthentication();

public ApiRestBasicAuthentication(String realm) {
super(realm);
}

@Override
public boolean checkCredentials(String user, String pwd) {
int authCode = authentication.authenticate(user, pwd);
return authCode == UserAuthentication.USER_AUTHENTICATED;
}

}


As this is now, check credentials is only checking if the user is authenticated.
But I'd like to check, if the method is POST, DELETE or PUT I should also check the specific credentials. But how can I get the method in my ApiRestBasicAuthentication? I'm doing that in my handler class



public void handle(HttpExchange httpExchange) throws IOException {
String method = httpExchange.getRequestMethod();
if ("post".equalsIgnoreCase(method)) {
createUser(httpExchange);
} else if ("get".equalsIgnoreCase(method)) {
readUsers(httpExchange);
} else if ("put".equalsIgnoreCase(method)) {
updateUser(httpExchange);
} else if ("delete".equalsIgnoreCase(method)) {
deleteUser(httpExchange);
}
}


Maybe this is supposed to be done some other way.
Any ideas?



Many thanks.










share|improve this question






















  • I suppose you'll need some authorisation aspect (or similiar functionality given by filter or interceptor) that will only respond to non-GETs if user is authorised, though I cannot help you right now with full answer. Figure out which of those (aspect, filter, interceptor) you have available and read about it.
    – Filip Malczak
    Dec 31 '16 at 11:16










  • That could work because I can check the method (POST, GET, PUT,...) in the filter, but then how can I get the username sent in the request inside the filter? My ApiRestBasicAuthentication has a checkCredentials() function which receives the user and password, but in the Filter I just have the httpExchange object, and the username/password is encripted.
    – David
    Dec 31 '16 at 17:31












  • I suggest you to use spring-security for that. Take a lookt at the following answer: stackoverflow.com/a/45965232/540286
    – Ortwin Angermeier
    Nov 9 '18 at 15:30














10












10








10


1





I'm using a very simple httpServer in Java for an api rest with GET, POST, PUT and DELETE. I'm using Basic Authentication and I have a couple classes Authentication.java and Authorisation.java which I use to authenticate and check permissions for the users.



So, the thing is that I want all users (authenticated) to be able to GET information from my api rest, but only users with certain privileges to be able to POST, PUT and DELETE. So how can I do that?



This is what I got



public class Server {

private static HttpServer server;

public static void start() throws IOException {

server = HttpServer.create(new InetSocketAddress(8000), 0);
HttpContext ctx = server.createContext("/users", new UserHandler());
ctx.setAuthenticator(new ApiRestBasicAuthentication("users"));

server.start();
}

}


And this is my ApiRestBasicAuthentication



public class ApiRestBasicAuthentication extends BasicAuthenticator {

private UserAuthentication authentication = new UserAuthentication();

public ApiRestBasicAuthentication(String realm) {
super(realm);
}

@Override
public boolean checkCredentials(String user, String pwd) {
int authCode = authentication.authenticate(user, pwd);
return authCode == UserAuthentication.USER_AUTHENTICATED;
}

}


As this is now, check credentials is only checking if the user is authenticated.
But I'd like to check, if the method is POST, DELETE or PUT I should also check the specific credentials. But how can I get the method in my ApiRestBasicAuthentication? I'm doing that in my handler class



public void handle(HttpExchange httpExchange) throws IOException {
String method = httpExchange.getRequestMethod();
if ("post".equalsIgnoreCase(method)) {
createUser(httpExchange);
} else if ("get".equalsIgnoreCase(method)) {
readUsers(httpExchange);
} else if ("put".equalsIgnoreCase(method)) {
updateUser(httpExchange);
} else if ("delete".equalsIgnoreCase(method)) {
deleteUser(httpExchange);
}
}


Maybe this is supposed to be done some other way.
Any ideas?



Many thanks.










share|improve this question













I'm using a very simple httpServer in Java for an api rest with GET, POST, PUT and DELETE. I'm using Basic Authentication and I have a couple classes Authentication.java and Authorisation.java which I use to authenticate and check permissions for the users.



So, the thing is that I want all users (authenticated) to be able to GET information from my api rest, but only users with certain privileges to be able to POST, PUT and DELETE. So how can I do that?



This is what I got



public class Server {

private static HttpServer server;

public static void start() throws IOException {

server = HttpServer.create(new InetSocketAddress(8000), 0);
HttpContext ctx = server.createContext("/users", new UserHandler());
ctx.setAuthenticator(new ApiRestBasicAuthentication("users"));

server.start();
}

}


And this is my ApiRestBasicAuthentication



public class ApiRestBasicAuthentication extends BasicAuthenticator {

private UserAuthentication authentication = new UserAuthentication();

public ApiRestBasicAuthentication(String realm) {
super(realm);
}

@Override
public boolean checkCredentials(String user, String pwd) {
int authCode = authentication.authenticate(user, pwd);
return authCode == UserAuthentication.USER_AUTHENTICATED;
}

}


As this is now, check credentials is only checking if the user is authenticated.
But I'd like to check, if the method is POST, DELETE or PUT I should also check the specific credentials. But how can I get the method in my ApiRestBasicAuthentication? I'm doing that in my handler class



public void handle(HttpExchange httpExchange) throws IOException {
String method = httpExchange.getRequestMethod();
if ("post".equalsIgnoreCase(method)) {
createUser(httpExchange);
} else if ("get".equalsIgnoreCase(method)) {
readUsers(httpExchange);
} else if ("put".equalsIgnoreCase(method)) {
updateUser(httpExchange);
} else if ("delete".equalsIgnoreCase(method)) {
deleteUser(httpExchange);
}
}


Maybe this is supposed to be done some other way.
Any ideas?



Many thanks.







java rest basic-authentication httpserver






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Dec 31 '16 at 10:31









DavidDavid

94121751




94121751












  • I suppose you'll need some authorisation aspect (or similiar functionality given by filter or interceptor) that will only respond to non-GETs if user is authorised, though I cannot help you right now with full answer. Figure out which of those (aspect, filter, interceptor) you have available and read about it.
    – Filip Malczak
    Dec 31 '16 at 11:16










  • That could work because I can check the method (POST, GET, PUT,...) in the filter, but then how can I get the username sent in the request inside the filter? My ApiRestBasicAuthentication has a checkCredentials() function which receives the user and password, but in the Filter I just have the httpExchange object, and the username/password is encripted.
    – David
    Dec 31 '16 at 17:31












  • I suggest you to use spring-security for that. Take a lookt at the following answer: stackoverflow.com/a/45965232/540286
    – Ortwin Angermeier
    Nov 9 '18 at 15:30


















  • I suppose you'll need some authorisation aspect (or similiar functionality given by filter or interceptor) that will only respond to non-GETs if user is authorised, though I cannot help you right now with full answer. Figure out which of those (aspect, filter, interceptor) you have available and read about it.
    – Filip Malczak
    Dec 31 '16 at 11:16










  • That could work because I can check the method (POST, GET, PUT,...) in the filter, but then how can I get the username sent in the request inside the filter? My ApiRestBasicAuthentication has a checkCredentials() function which receives the user and password, but in the Filter I just have the httpExchange object, and the username/password is encripted.
    – David
    Dec 31 '16 at 17:31












  • I suggest you to use spring-security for that. Take a lookt at the following answer: stackoverflow.com/a/45965232/540286
    – Ortwin Angermeier
    Nov 9 '18 at 15:30
















I suppose you'll need some authorisation aspect (or similiar functionality given by filter or interceptor) that will only respond to non-GETs if user is authorised, though I cannot help you right now with full answer. Figure out which of those (aspect, filter, interceptor) you have available and read about it.
– Filip Malczak
Dec 31 '16 at 11:16




I suppose you'll need some authorisation aspect (or similiar functionality given by filter or interceptor) that will only respond to non-GETs if user is authorised, though I cannot help you right now with full answer. Figure out which of those (aspect, filter, interceptor) you have available and read about it.
– Filip Malczak
Dec 31 '16 at 11:16












That could work because I can check the method (POST, GET, PUT,...) in the filter, but then how can I get the username sent in the request inside the filter? My ApiRestBasicAuthentication has a checkCredentials() function which receives the user and password, but in the Filter I just have the httpExchange object, and the username/password is encripted.
– David
Dec 31 '16 at 17:31






That could work because I can check the method (POST, GET, PUT,...) in the filter, but then how can I get the username sent in the request inside the filter? My ApiRestBasicAuthentication has a checkCredentials() function which receives the user and password, but in the Filter I just have the httpExchange object, and the username/password is encripted.
– David
Dec 31 '16 at 17:31














I suggest you to use spring-security for that. Take a lookt at the following answer: stackoverflow.com/a/45965232/540286
– Ortwin Angermeier
Nov 9 '18 at 15:30




I suggest you to use spring-security for that. Take a lookt at the following answer: stackoverflow.com/a/45965232/540286
– Ortwin Angermeier
Nov 9 '18 at 15:30












4 Answers
4






active

oldest

votes


















10





+100









A simple way to do it would be to change your
ApiRestBasicAuthentication like:



public class ApiRestBasicAuthentication extends BasicAuthenticator {

private UserAuthentication authentication = new UserAuthentication();

public ApiRestBasicAuthentication(String realm) {
super(realm);
}

@Override
public Authenticator.Result authenticate(HttpExchange exch) {
Authenticator.Result result=super.authenticate(exch);
if(result instanceof Authenticator.Success) {
HttpPrincipal principal=((Authenticator.Success)result).getPrincipal();
String requestMethod=exch.getRequestMethod();
if( ADD SOME LOGIC HERE FOR PRINCIPAL AND REQUEST METHOD) {
return new return new Authenticator.Failure(401);
}
return result;

}
}

@Override
public boolean checkCredentials(String user, String pwd) {
int authCode = authentication.authenticate(user, pwd);
return authCode == UserAuthentication.USER_AUTHENTICATED;
}

}


And add some logic there for requests/users that you want to fail the authenticator. I have shown you here how to get the method in the authenticate method but you need to specify the types of credentials.





Another solution would be if you check the source code of BasicAuthenticator you can see how it implements authenticate method and you can create your own implementation in a similar way instead of extending BasicAuthenticator and use the get method instead of just the username and password. You can see the source code here and I am sure you will be able to find your way around ;)



Usually in enterprise application you can use some external security management system - for example if you use Spring (the de facto standard in the current java web apps) you can use spring security and do such security patterns and filters in a more declarative way






share|improve this answer































    1














    While the above answers might be valid for you, I think you should also consider using defined roles and security-constraints which can be defined in your web.xml and used in the REST Resource using @RolesAllowed annotation. This then allows you to specifically allow permissions for methods individually or at the REST resource/class level.



    In web.xml, this looks something like this:-



    <security-role>
    <role-name>SERVERTOSERVER</role-name>
    </security-role>
    <security-constraint>
    <web-resource-collection>
    <web-resource-name>REST API description</web-resource-name>
    <url-pattern>/<path name>/*</url-pattern>
    <http-method>GET</http-method>
    </web-resource-collection>
    <auth-constraint>
    <description>Only allow users
    from following roles</description>
    <role-name>SERVERTOSERVER</role-name>
    </auth-constraint>
    </security-constraint>


    The following links have some examples: Purpose of roles tags in tomcat-users.xml? ,
    https://www.thecoderscorner.com/team-blog/hosting-servers/17-setting-up-role-based-security-in-tomcat/



    In case helpful, here is another type of solution for a Jersey based application: https://howtodoinjava.com/jersey/jersey-rest-security/






    share|improve this answer





















    • To what web.xml do you refer? Where does the @RolesAllowed annotation come from? Without having cross-checked I assume you are talking about a solution that is specific to a Tomcat server. Hence, this answer does not fit which the question above.
      – user2690527
      Nov 15 '18 at 13:22










    • javax.annotation.security.RolesAllowed, I have given a few examples of roles based access (tomcat / jersey based REST APIs)
      – Ankur Chrungoo
      Nov 15 '18 at 13:37










    • As you say yourself, your solution is tomcat/jersey based. Hence, it does not work with HttpServer (or HttpsServer) from the com.sun.net.httpserver-package.
      – user2690527
      Nov 16 '18 at 11:44










    • @RolesAllowed is a java annotation which works with security roles. I doubt what you are saying is entirely correct.
      – Ankur Chrungoo
      Nov 16 '18 at 11:46



















    0














    There might be many ways to solve this issue. Here is one of my proposal:




    1. Create a User Object with fields that you want and one field called something like "role". Lets say only "admins" are allowed to do make Http requests other than "GET" while "regular" users can only do "GET". Many ways to do this but one way is to make the "role" field String and assign values to it using an ENUM, so that it's easy to change later and only specific terms are used. But you don't have to do that. Write get and set method for the fields you create and that you might need later, and definitely for role.


    2. You need to make sure that class containing the handle(HttpExchange httpExchange) is able to see the currently logged in user, and refer to the User object associated with them. Then you need to modify the method so that



     



    if(loggedInUser.getRole().equals("admin")){
    //allow whatever method
    } else {
    // allow "GET" or give some denied permission error
    }


    Since other implementations have not been provided, I can't give a more detailed answer or be sure that this will work for you.






    share|improve this answer































      0














      I think what you should create an AuthenticationInterceptor and by-pass GET the requests there and correspondingly apply authentication mechanism for rest non-GET requests.



      public class AuthenticationInterceptor extends HandlerInterceptorAdapter {

      @Autowired
      private ApiRestBasicAuthentication apiRestBasicAuthentication;

      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      switch (request.getMethod()) {
      case "GET" :
      // by-passing all GET requests
      return true;

      default :
      return apiRestBasicAuthentication.checkCredentials(username, password);
      }
      }

      }





      share|improve this answer





















        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f41407510%2fjava-httpserver-basic-authentication-for-different-request-methods%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        4 Answers
        4






        active

        oldest

        votes








        4 Answers
        4






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        10





        +100









        A simple way to do it would be to change your
        ApiRestBasicAuthentication like:



        public class ApiRestBasicAuthentication extends BasicAuthenticator {

        private UserAuthentication authentication = new UserAuthentication();

        public ApiRestBasicAuthentication(String realm) {
        super(realm);
        }

        @Override
        public Authenticator.Result authenticate(HttpExchange exch) {
        Authenticator.Result result=super.authenticate(exch);
        if(result instanceof Authenticator.Success) {
        HttpPrincipal principal=((Authenticator.Success)result).getPrincipal();
        String requestMethod=exch.getRequestMethod();
        if( ADD SOME LOGIC HERE FOR PRINCIPAL AND REQUEST METHOD) {
        return new return new Authenticator.Failure(401);
        }
        return result;

        }
        }

        @Override
        public boolean checkCredentials(String user, String pwd) {
        int authCode = authentication.authenticate(user, pwd);
        return authCode == UserAuthentication.USER_AUTHENTICATED;
        }

        }


        And add some logic there for requests/users that you want to fail the authenticator. I have shown you here how to get the method in the authenticate method but you need to specify the types of credentials.





        Another solution would be if you check the source code of BasicAuthenticator you can see how it implements authenticate method and you can create your own implementation in a similar way instead of extending BasicAuthenticator and use the get method instead of just the username and password. You can see the source code here and I am sure you will be able to find your way around ;)



        Usually in enterprise application you can use some external security management system - for example if you use Spring (the de facto standard in the current java web apps) you can use spring security and do such security patterns and filters in a more declarative way






        share|improve this answer




























          10





          +100









          A simple way to do it would be to change your
          ApiRestBasicAuthentication like:



          public class ApiRestBasicAuthentication extends BasicAuthenticator {

          private UserAuthentication authentication = new UserAuthentication();

          public ApiRestBasicAuthentication(String realm) {
          super(realm);
          }

          @Override
          public Authenticator.Result authenticate(HttpExchange exch) {
          Authenticator.Result result=super.authenticate(exch);
          if(result instanceof Authenticator.Success) {
          HttpPrincipal principal=((Authenticator.Success)result).getPrincipal();
          String requestMethod=exch.getRequestMethod();
          if( ADD SOME LOGIC HERE FOR PRINCIPAL AND REQUEST METHOD) {
          return new return new Authenticator.Failure(401);
          }
          return result;

          }
          }

          @Override
          public boolean checkCredentials(String user, String pwd) {
          int authCode = authentication.authenticate(user, pwd);
          return authCode == UserAuthentication.USER_AUTHENTICATED;
          }

          }


          And add some logic there for requests/users that you want to fail the authenticator. I have shown you here how to get the method in the authenticate method but you need to specify the types of credentials.





          Another solution would be if you check the source code of BasicAuthenticator you can see how it implements authenticate method and you can create your own implementation in a similar way instead of extending BasicAuthenticator and use the get method instead of just the username and password. You can see the source code here and I am sure you will be able to find your way around ;)



          Usually in enterprise application you can use some external security management system - for example if you use Spring (the de facto standard in the current java web apps) you can use spring security and do such security patterns and filters in a more declarative way






          share|improve this answer


























            10





            +100







            10





            +100



            10




            +100




            A simple way to do it would be to change your
            ApiRestBasicAuthentication like:



            public class ApiRestBasicAuthentication extends BasicAuthenticator {

            private UserAuthentication authentication = new UserAuthentication();

            public ApiRestBasicAuthentication(String realm) {
            super(realm);
            }

            @Override
            public Authenticator.Result authenticate(HttpExchange exch) {
            Authenticator.Result result=super.authenticate(exch);
            if(result instanceof Authenticator.Success) {
            HttpPrincipal principal=((Authenticator.Success)result).getPrincipal();
            String requestMethod=exch.getRequestMethod();
            if( ADD SOME LOGIC HERE FOR PRINCIPAL AND REQUEST METHOD) {
            return new return new Authenticator.Failure(401);
            }
            return result;

            }
            }

            @Override
            public boolean checkCredentials(String user, String pwd) {
            int authCode = authentication.authenticate(user, pwd);
            return authCode == UserAuthentication.USER_AUTHENTICATED;
            }

            }


            And add some logic there for requests/users that you want to fail the authenticator. I have shown you here how to get the method in the authenticate method but you need to specify the types of credentials.





            Another solution would be if you check the source code of BasicAuthenticator you can see how it implements authenticate method and you can create your own implementation in a similar way instead of extending BasicAuthenticator and use the get method instead of just the username and password. You can see the source code here and I am sure you will be able to find your way around ;)



            Usually in enterprise application you can use some external security management system - for example if you use Spring (the de facto standard in the current java web apps) you can use spring security and do such security patterns and filters in a more declarative way






            share|improve this answer














            A simple way to do it would be to change your
            ApiRestBasicAuthentication like:



            public class ApiRestBasicAuthentication extends BasicAuthenticator {

            private UserAuthentication authentication = new UserAuthentication();

            public ApiRestBasicAuthentication(String realm) {
            super(realm);
            }

            @Override
            public Authenticator.Result authenticate(HttpExchange exch) {
            Authenticator.Result result=super.authenticate(exch);
            if(result instanceof Authenticator.Success) {
            HttpPrincipal principal=((Authenticator.Success)result).getPrincipal();
            String requestMethod=exch.getRequestMethod();
            if( ADD SOME LOGIC HERE FOR PRINCIPAL AND REQUEST METHOD) {
            return new return new Authenticator.Failure(401);
            }
            return result;

            }
            }

            @Override
            public boolean checkCredentials(String user, String pwd) {
            int authCode = authentication.authenticate(user, pwd);
            return authCode == UserAuthentication.USER_AUTHENTICATED;
            }

            }


            And add some logic there for requests/users that you want to fail the authenticator. I have shown you here how to get the method in the authenticate method but you need to specify the types of credentials.





            Another solution would be if you check the source code of BasicAuthenticator you can see how it implements authenticate method and you can create your own implementation in a similar way instead of extending BasicAuthenticator and use the get method instead of just the username and password. You can see the source code here and I am sure you will be able to find your way around ;)



            Usually in enterprise application you can use some external security management system - for example if you use Spring (the de facto standard in the current java web apps) you can use spring security and do such security patterns and filters in a more declarative way







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 12 '18 at 11:03

























            answered Nov 9 '18 at 15:05









            Veselin DavidovVeselin Davidov

            5,5861515




            5,5861515

























                1














                While the above answers might be valid for you, I think you should also consider using defined roles and security-constraints which can be defined in your web.xml and used in the REST Resource using @RolesAllowed annotation. This then allows you to specifically allow permissions for methods individually or at the REST resource/class level.



                In web.xml, this looks something like this:-



                <security-role>
                <role-name>SERVERTOSERVER</role-name>
                </security-role>
                <security-constraint>
                <web-resource-collection>
                <web-resource-name>REST API description</web-resource-name>
                <url-pattern>/<path name>/*</url-pattern>
                <http-method>GET</http-method>
                </web-resource-collection>
                <auth-constraint>
                <description>Only allow users
                from following roles</description>
                <role-name>SERVERTOSERVER</role-name>
                </auth-constraint>
                </security-constraint>


                The following links have some examples: Purpose of roles tags in tomcat-users.xml? ,
                https://www.thecoderscorner.com/team-blog/hosting-servers/17-setting-up-role-based-security-in-tomcat/



                In case helpful, here is another type of solution for a Jersey based application: https://howtodoinjava.com/jersey/jersey-rest-security/






                share|improve this answer





















                • To what web.xml do you refer? Where does the @RolesAllowed annotation come from? Without having cross-checked I assume you are talking about a solution that is specific to a Tomcat server. Hence, this answer does not fit which the question above.
                  – user2690527
                  Nov 15 '18 at 13:22










                • javax.annotation.security.RolesAllowed, I have given a few examples of roles based access (tomcat / jersey based REST APIs)
                  – Ankur Chrungoo
                  Nov 15 '18 at 13:37










                • As you say yourself, your solution is tomcat/jersey based. Hence, it does not work with HttpServer (or HttpsServer) from the com.sun.net.httpserver-package.
                  – user2690527
                  Nov 16 '18 at 11:44










                • @RolesAllowed is a java annotation which works with security roles. I doubt what you are saying is entirely correct.
                  – Ankur Chrungoo
                  Nov 16 '18 at 11:46
















                1














                While the above answers might be valid for you, I think you should also consider using defined roles and security-constraints which can be defined in your web.xml and used in the REST Resource using @RolesAllowed annotation. This then allows you to specifically allow permissions for methods individually or at the REST resource/class level.



                In web.xml, this looks something like this:-



                <security-role>
                <role-name>SERVERTOSERVER</role-name>
                </security-role>
                <security-constraint>
                <web-resource-collection>
                <web-resource-name>REST API description</web-resource-name>
                <url-pattern>/<path name>/*</url-pattern>
                <http-method>GET</http-method>
                </web-resource-collection>
                <auth-constraint>
                <description>Only allow users
                from following roles</description>
                <role-name>SERVERTOSERVER</role-name>
                </auth-constraint>
                </security-constraint>


                The following links have some examples: Purpose of roles tags in tomcat-users.xml? ,
                https://www.thecoderscorner.com/team-blog/hosting-servers/17-setting-up-role-based-security-in-tomcat/



                In case helpful, here is another type of solution for a Jersey based application: https://howtodoinjava.com/jersey/jersey-rest-security/






                share|improve this answer





















                • To what web.xml do you refer? Where does the @RolesAllowed annotation come from? Without having cross-checked I assume you are talking about a solution that is specific to a Tomcat server. Hence, this answer does not fit which the question above.
                  – user2690527
                  Nov 15 '18 at 13:22










                • javax.annotation.security.RolesAllowed, I have given a few examples of roles based access (tomcat / jersey based REST APIs)
                  – Ankur Chrungoo
                  Nov 15 '18 at 13:37










                • As you say yourself, your solution is tomcat/jersey based. Hence, it does not work with HttpServer (or HttpsServer) from the com.sun.net.httpserver-package.
                  – user2690527
                  Nov 16 '18 at 11:44










                • @RolesAllowed is a java annotation which works with security roles. I doubt what you are saying is entirely correct.
                  – Ankur Chrungoo
                  Nov 16 '18 at 11:46














                1












                1








                1






                While the above answers might be valid for you, I think you should also consider using defined roles and security-constraints which can be defined in your web.xml and used in the REST Resource using @RolesAllowed annotation. This then allows you to specifically allow permissions for methods individually or at the REST resource/class level.



                In web.xml, this looks something like this:-



                <security-role>
                <role-name>SERVERTOSERVER</role-name>
                </security-role>
                <security-constraint>
                <web-resource-collection>
                <web-resource-name>REST API description</web-resource-name>
                <url-pattern>/<path name>/*</url-pattern>
                <http-method>GET</http-method>
                </web-resource-collection>
                <auth-constraint>
                <description>Only allow users
                from following roles</description>
                <role-name>SERVERTOSERVER</role-name>
                </auth-constraint>
                </security-constraint>


                The following links have some examples: Purpose of roles tags in tomcat-users.xml? ,
                https://www.thecoderscorner.com/team-blog/hosting-servers/17-setting-up-role-based-security-in-tomcat/



                In case helpful, here is another type of solution for a Jersey based application: https://howtodoinjava.com/jersey/jersey-rest-security/






                share|improve this answer












                While the above answers might be valid for you, I think you should also consider using defined roles and security-constraints which can be defined in your web.xml and used in the REST Resource using @RolesAllowed annotation. This then allows you to specifically allow permissions for methods individually or at the REST resource/class level.



                In web.xml, this looks something like this:-



                <security-role>
                <role-name>SERVERTOSERVER</role-name>
                </security-role>
                <security-constraint>
                <web-resource-collection>
                <web-resource-name>REST API description</web-resource-name>
                <url-pattern>/<path name>/*</url-pattern>
                <http-method>GET</http-method>
                </web-resource-collection>
                <auth-constraint>
                <description>Only allow users
                from following roles</description>
                <role-name>SERVERTOSERVER</role-name>
                </auth-constraint>
                </security-constraint>


                The following links have some examples: Purpose of roles tags in tomcat-users.xml? ,
                https://www.thecoderscorner.com/team-blog/hosting-servers/17-setting-up-role-based-security-in-tomcat/



                In case helpful, here is another type of solution for a Jersey based application: https://howtodoinjava.com/jersey/jersey-rest-security/







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 15 '18 at 9:48









                Ankur ChrungooAnkur Chrungoo

                62039




                62039












                • To what web.xml do you refer? Where does the @RolesAllowed annotation come from? Without having cross-checked I assume you are talking about a solution that is specific to a Tomcat server. Hence, this answer does not fit which the question above.
                  – user2690527
                  Nov 15 '18 at 13:22










                • javax.annotation.security.RolesAllowed, I have given a few examples of roles based access (tomcat / jersey based REST APIs)
                  – Ankur Chrungoo
                  Nov 15 '18 at 13:37










                • As you say yourself, your solution is tomcat/jersey based. Hence, it does not work with HttpServer (or HttpsServer) from the com.sun.net.httpserver-package.
                  – user2690527
                  Nov 16 '18 at 11:44










                • @RolesAllowed is a java annotation which works with security roles. I doubt what you are saying is entirely correct.
                  – Ankur Chrungoo
                  Nov 16 '18 at 11:46


















                • To what web.xml do you refer? Where does the @RolesAllowed annotation come from? Without having cross-checked I assume you are talking about a solution that is specific to a Tomcat server. Hence, this answer does not fit which the question above.
                  – user2690527
                  Nov 15 '18 at 13:22










                • javax.annotation.security.RolesAllowed, I have given a few examples of roles based access (tomcat / jersey based REST APIs)
                  – Ankur Chrungoo
                  Nov 15 '18 at 13:37










                • As you say yourself, your solution is tomcat/jersey based. Hence, it does not work with HttpServer (or HttpsServer) from the com.sun.net.httpserver-package.
                  – user2690527
                  Nov 16 '18 at 11:44










                • @RolesAllowed is a java annotation which works with security roles. I doubt what you are saying is entirely correct.
                  – Ankur Chrungoo
                  Nov 16 '18 at 11:46
















                To what web.xml do you refer? Where does the @RolesAllowed annotation come from? Without having cross-checked I assume you are talking about a solution that is specific to a Tomcat server. Hence, this answer does not fit which the question above.
                – user2690527
                Nov 15 '18 at 13:22




                To what web.xml do you refer? Where does the @RolesAllowed annotation come from? Without having cross-checked I assume you are talking about a solution that is specific to a Tomcat server. Hence, this answer does not fit which the question above.
                – user2690527
                Nov 15 '18 at 13:22












                javax.annotation.security.RolesAllowed, I have given a few examples of roles based access (tomcat / jersey based REST APIs)
                – Ankur Chrungoo
                Nov 15 '18 at 13:37




                javax.annotation.security.RolesAllowed, I have given a few examples of roles based access (tomcat / jersey based REST APIs)
                – Ankur Chrungoo
                Nov 15 '18 at 13:37












                As you say yourself, your solution is tomcat/jersey based. Hence, it does not work with HttpServer (or HttpsServer) from the com.sun.net.httpserver-package.
                – user2690527
                Nov 16 '18 at 11:44




                As you say yourself, your solution is tomcat/jersey based. Hence, it does not work with HttpServer (or HttpsServer) from the com.sun.net.httpserver-package.
                – user2690527
                Nov 16 '18 at 11:44












                @RolesAllowed is a java annotation which works with security roles. I doubt what you are saying is entirely correct.
                – Ankur Chrungoo
                Nov 16 '18 at 11:46




                @RolesAllowed is a java annotation which works with security roles. I doubt what you are saying is entirely correct.
                – Ankur Chrungoo
                Nov 16 '18 at 11:46











                0














                There might be many ways to solve this issue. Here is one of my proposal:




                1. Create a User Object with fields that you want and one field called something like "role". Lets say only "admins" are allowed to do make Http requests other than "GET" while "regular" users can only do "GET". Many ways to do this but one way is to make the "role" field String and assign values to it using an ENUM, so that it's easy to change later and only specific terms are used. But you don't have to do that. Write get and set method for the fields you create and that you might need later, and definitely for role.


                2. You need to make sure that class containing the handle(HttpExchange httpExchange) is able to see the currently logged in user, and refer to the User object associated with them. Then you need to modify the method so that



                 



                if(loggedInUser.getRole().equals("admin")){
                //allow whatever method
                } else {
                // allow "GET" or give some denied permission error
                }


                Since other implementations have not been provided, I can't give a more detailed answer or be sure that this will work for you.






                share|improve this answer




























                  0














                  There might be many ways to solve this issue. Here is one of my proposal:




                  1. Create a User Object with fields that you want and one field called something like "role". Lets say only "admins" are allowed to do make Http requests other than "GET" while "regular" users can only do "GET". Many ways to do this but one way is to make the "role" field String and assign values to it using an ENUM, so that it's easy to change later and only specific terms are used. But you don't have to do that. Write get and set method for the fields you create and that you might need later, and definitely for role.


                  2. You need to make sure that class containing the handle(HttpExchange httpExchange) is able to see the currently logged in user, and refer to the User object associated with them. Then you need to modify the method so that



                   



                  if(loggedInUser.getRole().equals("admin")){
                  //allow whatever method
                  } else {
                  // allow "GET" or give some denied permission error
                  }


                  Since other implementations have not been provided, I can't give a more detailed answer or be sure that this will work for you.






                  share|improve this answer


























                    0












                    0








                    0






                    There might be many ways to solve this issue. Here is one of my proposal:




                    1. Create a User Object with fields that you want and one field called something like "role". Lets say only "admins" are allowed to do make Http requests other than "GET" while "regular" users can only do "GET". Many ways to do this but one way is to make the "role" field String and assign values to it using an ENUM, so that it's easy to change later and only specific terms are used. But you don't have to do that. Write get and set method for the fields you create and that you might need later, and definitely for role.


                    2. You need to make sure that class containing the handle(HttpExchange httpExchange) is able to see the currently logged in user, and refer to the User object associated with them. Then you need to modify the method so that



                     



                    if(loggedInUser.getRole().equals("admin")){
                    //allow whatever method
                    } else {
                    // allow "GET" or give some denied permission error
                    }


                    Since other implementations have not been provided, I can't give a more detailed answer or be sure that this will work for you.






                    share|improve this answer














                    There might be many ways to solve this issue. Here is one of my proposal:




                    1. Create a User Object with fields that you want and one field called something like "role". Lets say only "admins" are allowed to do make Http requests other than "GET" while "regular" users can only do "GET". Many ways to do this but one way is to make the "role" field String and assign values to it using an ENUM, so that it's easy to change later and only specific terms are used. But you don't have to do that. Write get and set method for the fields you create and that you might need later, and definitely for role.


                    2. You need to make sure that class containing the handle(HttpExchange httpExchange) is able to see the currently logged in user, and refer to the User object associated with them. Then you need to modify the method so that



                     



                    if(loggedInUser.getRole().equals("admin")){
                    //allow whatever method
                    } else {
                    // allow "GET" or give some denied permission error
                    }


                    Since other implementations have not been provided, I can't give a more detailed answer or be sure that this will work for you.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Nov 9 '18 at 14:49









                    Tezra

                    5,02621042




                    5,02621042










                    answered Nov 9 '18 at 14:07









                    spinyBabblerspinyBabbler

                    858




                    858























                        0














                        I think what you should create an AuthenticationInterceptor and by-pass GET the requests there and correspondingly apply authentication mechanism for rest non-GET requests.



                        public class AuthenticationInterceptor extends HandlerInterceptorAdapter {

                        @Autowired
                        private ApiRestBasicAuthentication apiRestBasicAuthentication;

                        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                        switch (request.getMethod()) {
                        case "GET" :
                        // by-passing all GET requests
                        return true;

                        default :
                        return apiRestBasicAuthentication.checkCredentials(username, password);
                        }
                        }

                        }





                        share|improve this answer


























                          0














                          I think what you should create an AuthenticationInterceptor and by-pass GET the requests there and correspondingly apply authentication mechanism for rest non-GET requests.



                          public class AuthenticationInterceptor extends HandlerInterceptorAdapter {

                          @Autowired
                          private ApiRestBasicAuthentication apiRestBasicAuthentication;

                          public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                          switch (request.getMethod()) {
                          case "GET" :
                          // by-passing all GET requests
                          return true;

                          default :
                          return apiRestBasicAuthentication.checkCredentials(username, password);
                          }
                          }

                          }





                          share|improve this answer
























                            0












                            0








                            0






                            I think what you should create an AuthenticationInterceptor and by-pass GET the requests there and correspondingly apply authentication mechanism for rest non-GET requests.



                            public class AuthenticationInterceptor extends HandlerInterceptorAdapter {

                            @Autowired
                            private ApiRestBasicAuthentication apiRestBasicAuthentication;

                            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                            switch (request.getMethod()) {
                            case "GET" :
                            // by-passing all GET requests
                            return true;

                            default :
                            return apiRestBasicAuthentication.checkCredentials(username, password);
                            }
                            }

                            }





                            share|improve this answer












                            I think what you should create an AuthenticationInterceptor and by-pass GET the requests there and correspondingly apply authentication mechanism for rest non-GET requests.



                            public class AuthenticationInterceptor extends HandlerInterceptorAdapter {

                            @Autowired
                            private ApiRestBasicAuthentication apiRestBasicAuthentication;

                            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                            switch (request.getMethod()) {
                            case "GET" :
                            // by-passing all GET requests
                            return true;

                            default :
                            return apiRestBasicAuthentication.checkCredentials(username, password);
                            }
                            }

                            }






                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Nov 9 '18 at 15:22









                            swayamrainaswayamraina

                            588610




                            588610






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.





                                Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                Please pay close attention to the following guidance:


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f41407510%2fjava-httpserver-basic-authentication-for-different-request-methods%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                Full-time equivalent

                                Bicuculline

                                さくらももこ