View Javadoc
1   /*
2    * JBoss, Home of Professional Open Source
3    * Copyright 2014, Red Hat, Inc. and/or its affiliates, and individual
4    * contributors by the @authors tag. See the copyright.txt in the
5    * distribution for a full listing of individual contributors.
6    *
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   * http://www.apache.org/licenses/LICENSE-2.0
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.jboss.as.quickstarts.ejb_security_interceptors;
18  
19  import static org.jboss.as.quickstarts.ejb_security_interceptors.EJBUtil.lookupIntermediateEJB;
20  import static org.jboss.as.quickstarts.ejb_security_interceptors.EJBUtil.lookupSecuredEJB;
21  
22  import java.io.IOException;
23  import java.util.HashMap;
24  import java.util.Map;
25  
26  import javax.ejb.EJBAccessException;
27  import javax.security.auth.Subject;
28  import javax.security.auth.callback.Callback;
29  import javax.security.auth.callback.CallbackHandler;
30  import javax.security.auth.callback.NameCallback;
31  import javax.security.auth.callback.PasswordCallback;
32  import javax.security.auth.callback.UnsupportedCallbackException;
33  import javax.security.auth.login.AppConfigurationEntry;
34  import javax.security.auth.login.Configuration;
35  import javax.security.auth.login.LoginContext;
36  import javax.security.auth.login.LoginException;
37  
38  import org.jboss.security.ClientLoginModule;
39  import org.jboss.security.SimplePrincipal;
40  
41  /**
42   * The remote client responsible for making a number of calls to the server to demonstrate the capabilities of the interceptors.
43   * 
44   * @author <a href="mailto:darran.lofthouse@jboss.com">Darran Lofthouse</a>
45   */
46  public class RemoteClient {
47  
48      /**
49       * Perform the tests of this quick start using the SecurityContextAssociation API to set the desired Principal.
50       */
51      private static void performTestingSecurityContext(final String user, final SecuredEJBRemote secured,
52          final IntermediateEJBRemote intermediate) {
53          try {
54              if (user != null) {
55                  SecurityActions.securityContextSetPrincpal(new SimplePrincipal(user));
56              }
57  
58              System.out.println("-------------------------------------------------");
59              System.out
60                  .println(String.format("* * About to perform test as %s * *\n\n", user == null ? "ConnectionUser" : user));
61  
62              makeCalls(secured, intermediate);
63          } finally {
64              SecurityActions.securityContextClear();
65              System.out.println("* * Test Complete * * \n\n\n");
66              System.out.println("-------------------------------------------------");
67          }
68      }
69  
70      /**
71       * Perform the tests of this quick start using the ClientLoginModule and LoginContext API to set the desired Principal.
72       */
73      private static void performTestingClientLoginModule(final String user, final SecuredEJBRemote secured,
74          final IntermediateEJBRemote intermediate) throws Exception {
75          LoginContext loginContext = null;
76          try {
77              if (user != null) {
78                  loginContext = getCLMLoginContext(user, "");
79                  loginContext.login();
80              }
81  
82              System.out.println("-------------------------------------------------");
83              System.out
84                  .println(String.format("* * About to perform test as %s * *\n\n", user == null ? "ConnectionUser" : user));
85  
86              makeCalls(secured, intermediate);
87          } finally {
88              if (loginContext != null) {
89                  loginContext.logout();
90              }
91              System.out.println("* * Test Complete * * \n\n");
92              System.out.println("-------------------------------------------------");
93          }
94      }
95  
96      public static LoginContext getCLMLoginContext(final String username, final String password) throws LoginException {
97          final String configurationName = "Testing";
98  
99          CallbackHandler cbh = new CallbackHandler() {
100             public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
101                 for (Callback current : callbacks) {
102                     if (current instanceof NameCallback) {
103                         ((NameCallback) current).setName(username);
104                     } else if (current instanceof PasswordCallback) {
105                         ((PasswordCallback) current).setPassword(password.toCharArray());
106                     } else {
107                         throw new UnsupportedCallbackException(current);
108                     }
109                 }
110             }
111         };
112         Configuration config = new Configuration() {
113 
114             @Override
115             public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
116                 if (configurationName.equals(name) == false) {
117                     throw new IllegalArgumentException("Unexpected configuration name '" + name + "'");
118                 }
119                 Map<String, String> options = new HashMap<String, String>();
120                 options.put("multi-threaded", "true");
121                 options.put("restore-login-identity", "true");
122 
123                 AppConfigurationEntry clmEntry = new AppConfigurationEntry(ClientLoginModule.class.getName(),
124                     AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
125 
126                 return new AppConfigurationEntry[] { clmEntry };
127             }
128         };
129 
130         return new LoginContext(configurationName, new Subject(), cbh, config);
131     }
132 
133     private static void makeCalls(final SecuredEJBRemote secured, final IntermediateEJBRemote intermediate) {
134         System.out.println("* Making Direct Calls to the SecuredEJB\n");
135         System.out.println(String.format("* getSecurityInformation()=%s", secured.getSecurityInformation()));
136 
137         boolean roleMethodSuccess;
138         try {
139             secured.roleOneMethod();
140             roleMethodSuccess = true;
141         } catch (EJBAccessException e) {
142             roleMethodSuccess = false;
143         }
144         System.out.println(String.format("* Can call roleOneMethod()=%b", roleMethodSuccess));
145 
146         try {
147             secured.roleTwoMethod();
148             roleMethodSuccess = true;
149         } catch (EJBAccessException e) {
150             roleMethodSuccess = false;
151         }
152         System.out.println(String.format("* Can call roleTwoMethod()=%b", roleMethodSuccess));
153 
154         System.out.println("\n* Calling the IntermediateEJB to repeat the test server to server \n");
155         System.out.println(intermediate.makeTestCalls());
156     }
157 
158     /**
159      * @param args
160      */
161     public static void main(String[] args) throws Exception {
162         System.out.println("\n\n\n* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\n");
163 
164         SecuredEJBRemote secured = lookupSecuredEJB();
165         IntermediateEJBRemote intermediate = lookupIntermediateEJB();
166 
167         System.out
168             .println("This first round of tests is using the (PicketBox) SecurityContextAssociation API to set the desired Principal.\n\n");
169 
170         performTestingSecurityContext(null, secured, intermediate);
171         performTestingSecurityContext("AppUserOne", secured, intermediate);
172         performTestingSecurityContext("AppUserTwo", secured, intermediate);
173         try {
174             performTestingSecurityContext("AppUserThree", secured, intermediate);
175             System.err.println("ERROR - We did not expect the switch to 'AppUserThree' to work.");
176         } catch (Exception e) {
177             System.out.println("Call as 'AppUserThree' correctly rejected.\n");
178         }
179 
180         System.out
181             .println("This second round of tests is using the (PicketBox) ClientLoginModule with LoginContext API to set the desired Principal.\n\n");
182 
183         performTestingClientLoginModule(null, secured, intermediate);
184         performTestingClientLoginModule("AppUserOne", secured, intermediate);
185         performTestingClientLoginModule("AppUserTwo", secured, intermediate);
186         try {
187             performTestingClientLoginModule("AppUserThree", secured, intermediate);
188             System.err.println("ERROR - We did not expect the switch to 'AppUserThree' to work.");
189         } catch (Exception e) {
190             System.out.println("Call as 'AppUserThree' correctly rejected.\n");
191         }
192 
193         System.out.println("\n\n* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\n\n");
194     }
195 
196 }