source: branches/2.2.0.1/security/ExpressoCertLogin/src/LoginApplet.java @ 4124

Revision 4124, 12.9 KB checked in by rafaelraymundo, 13 years ago (diff)

Ticket #1739 - Login com certificado em atributo customizável.

Line 
1
2import java.awt.Frame;
3import java.io.IOException;
4import java.net.MalformedURLException;
5import java.net.URL;
6import java.security.GeneralSecurityException;
7import java.security.ProviderException;
8
9import javax.net.ssl.SSLHandshakeException;
10import javax.swing.JApplet;
11import javax.swing.JOptionPane;
12import javax.swing.SwingUtilities;
13import org.apache.commons.httpclient.HttpException;
14
15import netscape.javascript.JSObject;
16
17import br.gov.serpro.cert.DigitalCertificate;
18import br.gov.serpro.setup.Setup;
19import br.gov.serpro.ui.DialogBuilder;
20
21/**
22 * GUI que realiza o login com certificados A1 e A3 ou login com usuário e senha no expresso.
23 * Esta classe estende a classe JApplet
24 * @author Mário César Kolling - mario.kolling@serpro.gov.br
25 */
26public class LoginApplet extends JApplet {
27
28    /**
29     * Valor gerado aleatoriamente
30     */
31    //TODO: Alterar a cor e fonte dos labels e das caixas de texto e senha.
32    private static final long serialVersionUID = -6204158613173951516L;
33    private DigitalCertificate dc;
34    private Setup setup;
35
36    /* (non-Javadoc)
37     * @see java.applet.Applet#init()
38     */
39    public void init() {
40        super.init();
41        this.setSize(0, 0);
42        this.setup = new Setup(this);
43        this.setup.addLanguageResource("ExpressoCertLoginMessages");
44    }
45   
46    private boolean parseVercert(String[] answer, String certificate){
47        boolean tryAgain = false;
48        // Faz o login
49        if (setup.getParameter("debug").equalsIgnoreCase("true") && answer != null) {
50            System.out.println("Código de retorno: " + answer[0].trim());
51        }
52
53        if (answer == null){ // Ação cancelada
54            tryAgain = false;
55            String redirect = this.getCodeBase().getProtocol() + "://" + this.getCodeBase().getHost()
56                    + ":" + this.getCodeBase().getPort() + "/login.php";
57            try {
58                this.getAppletContext().showDocument(new URL(redirect));
59            } catch (MalformedURLException e) {
60                // TODO Bloco catch gerado automaticamente
61                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
62                    e.printStackTrace();
63                }
64            }
65        }
66        else if (Integer.parseInt(answer[0].trim()) == 0) {
67
68            tryAgain = false;
69            // Pega usuário e senha de credentials[1] e credentials[2], respectivamente
70            // adiciona na página e faz o submit.
71            JSObject document = (JSObject) JSObject.getWindow(this).getMember("document");
72            JSObject loginForm = (JSObject) document.getMember("flogin");
73            JSObject loginField = (JSObject) loginForm.getMember("user");
74            loginField.setMember("value", answer[1].trim());
75
76            JSObject passwdField = (JSObject) loginForm.getMember("passwd");
77            passwdField.setMember("value", answer[2].trim());
78
79            JSObject certificateField = (JSObject) loginForm.getMember("certificado");
80            certificateField.setMember("value", certificate.trim());
81
82            loginForm.call("submit", null);
83            Thread.yield();
84
85        } else if (Integer.parseInt(answer[0].trim()) == 6) {
86
87            tryAgain = false;
88
89            if (setup.getParameter("debug").equalsIgnoreCase("true")) {
90                System.out.println("Mensagem de retorno: " + answer[1].trim());
91            }
92
93            DialogBuilder.showMessageDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this), answer[1].trim(), this.setup);
94
95            String redirect = this.getCodeBase().getProtocol() + "://" + this.getCodeBase().getHost()
96                    + ":" + this.getCodeBase().getPort() + "/login.php?cd=98&ts=202";
97            try {
98                this.getAppletContext().showDocument(new URL(redirect));
99            } catch (MalformedURLException e) {
100                // TODO Bloco catch gerado automaticamente
101                if (this.setup.getParameter("debug").equalsIgnoreCase("true")) {
102                    e.printStackTrace();
103                }
104            }
105        } else {
106            tryAgain = true;
107            dc.destroy();
108            System.gc();
109
110            if (setup.getParameter("debug").equalsIgnoreCase("true")) {
111                System.out.println("Mensagem de retorno: " + answer[1].trim());
112            }
113
114            // Mostra mensagem de erro para o usuário
115            DialogBuilder.showMessageDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this), answer[1].trim(), this.setup);
116            Thread.yield();
117        }
118
119        return tryAgain;
120    }
121
122    private boolean parseHandleCertificateResponse(String certificate){
123       
124        // Envia certificado
125       
126        JSObject document = (JSObject) JSObject.getWindow(this).getMember("document");
127        JSObject certificateForm = (JSObject) document.getMember("certificateForm");
128        JSObject certificateField = (JSObject) certificateForm.getMember("certificado");
129        certificateField.setMember("value", certificate);
130
131        // submit e cai fora
132        certificateForm.call("submit", null);
133       
134        dc.destroy();
135        System.gc();
136        Thread.yield();
137
138        return false;
139    }
140
141    /* (non-Javadoc)
142     * @see java.applet.Applet#start()
143     */
144    @Override
145    public void start() {
146        super.start();
147
148        int useCertificate = DigitalCertificate.KEYSTORE_NOT_DETECTED;
149        boolean tryAgain = true;
150
151        do {
152
153            // Cria uma instância de DigitalCertificate e a inicializa
154            // Aqui pega document base e verifica em que aplicação estamos.
155
156            this.dc = new DigitalCertificate(this.getDocumentBase(), setup);
157            useCertificate = dc.init();
158
159            try {
160
161                String redirect = "";
162
163                // Testa em qual aplicação estamos.
164                URL documentURL = this.getDocumentBase();
165
166                if (documentURL.getPath().matches(".*login.php$")){
167                    redirect = this.getCodeBase().getProtocol() + "://" + this.getCodeBase().getHost()
168                        + ":" + this.getCodeBase().getPort() + "/login.php";
169                }
170                else {
171                    redirect = this.getCodeBase().getProtocol() + "://" + this.getCodeBase().getHost()
172                        + ":" + this.getCodeBase().getPort() + "/preferences/index.php";
173                }
174
175                switch (useCertificate) {
176                    case DigitalCertificate.KEYSTORE_DETECTED:
177                        // Mostra PinNeedeDialog.
178                        String pin = DialogBuilder.showPinDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this), this.setup);
179                       
180                        if (pin != null) {
181                            dc.openKeyStore(pin.toCharArray());
182                            if (documentURL.getPath().matches(".*login.php$")){
183                                tryAgain = parseVercert(dc.getCredentials(pin, new URL(this.getCodeBase().getProtocol()+"://" +
184                                    this.getCodeBase().getHost() + ":" + this.getCodeBase().getPort() +
185                                    "/security/vercert.php")), dc.getPEMCertificate());
186                            }
187                            else {
188                                tryAgain = parseHandleCertificateResponse(dc.getPEMCertificate());
189                            }
190
191                        } else {
192
193                            // TODO: Notifica usuário
194                            tryAgain = false;
195                            try {
196                                this.getAppletContext().showDocument(new URL(redirect));
197                            } catch (MalformedURLException e) {
198                                // TODO Bloco catch gerado automaticamente
199                                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
200                                    e.printStackTrace();
201                                }
202                            }
203                        }
204
205                        break;
206                    default:
207
208                        // TODO: notifica usuário que token não foi encontrado
209                        // ou repositório de chaves públicas não foi configurado.
210                        // Tentar carregar token/keystore novamente? / Logon sem certificado digital?
211
212                        tryAgain = false;
213                        if (setup.getParameter("debug").equalsIgnoreCase("true")) {
214                            System.out.println("não achou token");
215                        }
216
217                        dc.destroy();
218                        System.gc();
219
220                        try {
221                            this.getAppletContext().showDocument(new URL(redirect));
222                        } catch (MalformedURLException e) {
223                            // TODO Bloco catch gerado automaticamente
224                            if (setup.getParameter("debug").equalsIgnoreCase("true")) {
225                                e.printStackTrace();
226                            }
227                        }
228                }
229
230            } catch (SSLHandshakeException e) {
231                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
232                    e.printStackTrace();
233                }
234                dc.destroy();
235                System.gc();
236                DialogBuilder.showMessageDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this),
237                        this.setup.getLang("ExpressoCertLoginMessages", "LoginApplet001"), this.setup);
238
239                Thread.yield();
240
241                tryAgain = true;
242            } catch (HttpException e) {
243                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
244                    e.printStackTrace();
245                }
246
247                tryAgain = true;
248                Thread.yield();
249            } catch (GeneralSecurityException e) {
250                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
251                    e.printStackTrace();
252                }
253
254                DialogBuilder.showMessageDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this),
255                        this.setup.getLang("ExpressoCertLoginMessages", "LoginApplet002"), this.setup);
256
257                Thread.yield();
258                tryAgain = true;
259            } catch (IOException e) {
260                dc.destroy();
261                System.gc();
262
263                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
264                    e.printStackTrace();
265                }
266
267                Throwable cause = null;
268                if ((cause = e.getCause()) != null) {
269                    if (cause instanceof javax.security.auth.login.LoginException) {
270                        DialogBuilder.showMessageDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this), this.setup.getLang("ExpressoCertLoginMessages", "LoginApplet003"), this.setup);
271                    } else {
272                        if (setup.getParameter("debug").equalsIgnoreCase("true")) {
273                            System.out.println("Exception lançada: " + cause.getClass().getCanonicalName());
274                        }
275                    }
276                } else {
277                    if (e instanceof java.net.ConnectException) {
278                        DialogBuilder.showMessageDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this),
279                                this.setup.getLang("ExpressoCertLoginMessages", "LoginApplet004"), this.setup);
280                    } else {
281                        if (setup.getParameter("debug").equalsIgnoreCase("true")) {
282                            System.out.println("Exception lançada: " + e.getClass().getCanonicalName());
283                        }
284                    }
285                }
286
287                Thread.yield();
288                tryAgain = true;
289            } catch (ProviderException e) {
290
291                dc.destroy();
292                System.gc();
293
294                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
295                    e.printStackTrace();
296                }
297
298                int resultado = DialogBuilder.showConfirmDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this),
299                        //"Deseja tentar carregá-lo novamente?",
300                        this.setup.getLang("ExpressoCertLoginMessages", "LoginApplet005"),
301                        JOptionPane.QUESTION_MESSAGE,
302                        JOptionPane.OK_CANCEL_OPTION, this.setup);
303
304                if (resultado == JOptionPane.OK_OPTION) {
305                    tryAgain = true;
306                } else {
307                    tryAgain = false;
308                }
309
310                Thread.yield();
311            }
312
313        } while (tryAgain);
314
315    }
316
317    /**
318     * Destrói a Applet, executando códigos para desregistrar tokens, keystores, etc.
319     */
320    @Override
321    public void stop() {
322        //super.destroy();
323        if (setup.getParameter("debug").equalsIgnoreCase("true")) {
324            System.out.println("Finalizando Applet de Login!");
325        }
326
327        this.dc.destroy();
328        this.dc = null;
329        System.gc();
330    }
331}
Note: See TracBrowser for help on using the repository browser.