简体   繁体   中英

HTTP Error 401 while calling RESTFul Web service from a RESTFul client (both are on the same security domain) in JBOSS EAP 6.3

I have 2 web apps - empService and empClient. I am just printing a "Hello World" message from service. I put both these apps on the same security domain. When I call my service app directly, it asks for login credentials to open the webpage. But when I call it from the client, it is throwing HTTP Error 401 (unauthorized). Since they both use same security domain, client should also be granted access when I call the service right. Can someone please let me know if I need to add something else to the code here.

empService
   - src
      - com.channel.employee.service
         - Employee
         - EmployeeService
   - WebContent
      - WEB-INF
         - classes
            - employee-roles.properties
            - employee-users.properties
         - jboss-web.xml
         - web.xml
      - hello.jsp
empClient
   - src
      - com.channel.employee.client
         - EmployeeClient
   - WebContent
      - WEB-INF
         - classes
            - employee-roles.properties
            - employee-users.properties
         - jboss-web.xml
         - web.xml
Employee.java
    @Path("/")
        public class Employee {
            /*@Inject
            static EmployeeService employeeService;*/

            EmployeeService employeeService=new EmployeeService();

            @GET
            @Path("/xml")
            @Produces({ "application/xml" })
            @RolesAllowed({"employee"})
            public String getHelloWorldXML() {
                return "<xml><result>" +    employeeService.createHelloMessage("Employee") + "</result></xml>";
            }

        }

EmployeeService.java
    public class EmployeeService {

        String createHelloMessage(String name) {
            return "Hello " + name + "!";
        }

    }
employee-roles.properties
    usaaemp1=employee
    usaaemp2=employee
employee-users.properties
    usaaemp1=usaaemp11
    usaaemp2=usaaemp22
jboss-web.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <jboss-web>
        <security-domain>java:/jaas/Employee</security-domain>
    </jboss-web>
web.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
      <display-name>empService</display-name>
        <welcome-file-list>
            <welcome-file>hello.jsp</welcome-file>
        </welcome-file-list>

        <context-param>
            <param-name>resteasy.role.based.security</param-name>
            <param-value>true</param-value>
        </context-param>

       <servlet-mapping>
            <servlet-name>javax.ws.rs.core.Application</servlet-name>
            <url-pattern>/employee/*</url-pattern>
        </servlet-mapping>

        <security-constraint>
            <web-resource-collection>
                <web-resource-name>EmployeeChannel</web-resource-name>
                <url-pattern>/employee/*</url-pattern>
                <http-method>GET</http-method>
                <http-method>POST</http-method>
            </web-resource-collection>
            <auth-constraint>
                <role-name>employee</role-name>
            </auth-constraint>
        </security-constraint>

        <login-config>
            <auth-method>BASIC</auth-method>
            <!-- <realm-name>Specify Realm Name Here</realm-name> -->
        </login-config>
        <security-role>
            <role-name>employee</role-name>
        </security-role>

    </web-app>
hello.jsp
    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Insert title here</title>
    </head>
    <body>
        <a href="employee/xml">Employee Channel</a>
    </body>
    </html>
EmployeeClient.java
    public class EmployeeClient {

        public static void main(String[] args){

            try{
                //Initiate a client request using the url as a parameter
                ClientRequest request = new ClientRequest("http://localhost:8080/ent_securityprefs_empService/employee/xml");
                request.accept("application/xml");

                //To get the response based on the request
                ClientResponse<String> response = request.get(String.class);

                //Check the HTTP status of the request
                //HTTP 200 indicates the request is OK
                if(response.getStatus() != 200){
                    throw new RuntimeException("Failed request with HTTP status: "+response.getStatus());
                }

                //If we get a good response, now let's read it
                BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(response.getEntity().getBytes())));

                String output;

                //Loop over the br in order to print out the contents
                System.out.println("\n*** Response from Server ***\n");
                while((output = br.readLine()) != null){
                    System.out.println(output);
                }
            } catch(ClientProtocolException cpe) {
                System.err.println(cpe);
            } catch(IOException ioe){
                System.err.println(ioe);
            } catch(Exception e){
                System.err.println(e);
            }

        }

    }
web.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
      <display-name>empClient</display-name>
      <security-constraint>
            <web-resource-collection>
                <web-resource-name>EmployeeChannel</web-resource-name>
                <url-pattern>/*</url-pattern>
                <http-method>GET</http-method>
                <http-method>POST</http-method>
            </web-resource-collection>
            <auth-constraint>
                <role-name>employee</role-name>
            </auth-constraint>
        </security-constraint>
        <login-config>
            <auth-method>BASIC</auth-method>
            <!-- <realm-name>Specify Realm Name Here</realm-name> -->
        </login-config>
        <security-role>
            <role-name>employee</role-name>
        </security-role>
    </web-app>
standalone-full.xml
    <security-domain name="Employee" cache-type="default">
                        <authentication>
                            <login-module code="UsersRoles" flag="required">
                                <module-option name="usersProperties" value="employee-users.properties"/>
                                <module-option name="rolesProperties" value="employee-roles.properties"/>
                            </login-module>
                        </authentication>
                    </security-domain>

I think that you will need to send 'login credentials' during the Client's request.

I recommend always looking at the error codes being returned by a server, generally , they will give an explanation of the problem.

10.4.2 401 Unauthorized

The request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource. The client MAY repeat the request with a suitable Authorization header field (section 14.8). If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials. If the 401 response contains the same challenge as the prior response, and the user agent has already attempted authentication at least once, then the user SHOULD be presented the entity that was given in the response, since that entity might include relevant diagnostic information. HTTP access authentication is explained in "HTTP Authentication: Basic and Digest Access Authentication"

The above quote is from: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html


[edit]
I didn't read your post as clearly as I should have, I didn't notice that your client was its own process.

But I am going to leave the following text that was part of the original answer:

Even though your client and server are in the same application, an external http request is being made, meaning that the call will leave the JVM and then get routed back to the JVM by the underlying hardware and infrastructure.

Meaning, that your application will have to authenticate and authorize itself when calling itself via http(s).

[/edit]

I can now call the client with no 401 error. I am not sure of this is what worked for me, because I tried lot of different things.

Employee.java

 @Path("/")
        public class Employee {
            @Inject
            static EmployeeService employeeService;

            @GET
            @Path("/xml")
            @Produces({ "application/xml" })
            @RolesAllowed({"employee"})
            public String getHelloWorldXML() {
                return "<xml><result>" +    employeeService.createHelloMessage("Employee") + "</result></xml>";
            }

        }

Added beans.xml file to WEB-INF folder.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
      http://java.sun.com/xml/ns/javaee 
      http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">

      <!-- An application that uses CDI must have a file named beans.xml. 
      The file can be completely empty (it has content only in certain 
      limited situations), but it must be present. -->

</beans>

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