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

Revision 4123, 12.7 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){
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            loginForm.call("submit", null);
80            Thread.yield();
81
82        } else if (Integer.parseInt(answer[0].trim()) == 6) {
83
84            tryAgain = false;
85
86            if (setup.getParameter("debug").equalsIgnoreCase("true")) {
87                System.out.println("Mensagem de retorno: " + answer[1].trim());
88            }
89
90            DialogBuilder.showMessageDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this), answer[1].trim(), this.setup);
91
92            String redirect = this.getCodeBase().getProtocol() + "://" + this.getCodeBase().getHost()
93                    + ":" + this.getCodeBase().getPort() + "/login.php?cd=98&ts=202";
94            try {
95                this.getAppletContext().showDocument(new URL(redirect));
96            } catch (MalformedURLException e) {
97                // TODO Bloco catch gerado automaticamente
98                if (this.setup.getParameter("debug").equalsIgnoreCase("true")) {
99                    e.printStackTrace();
100                }
101            }
102        } else {
103            tryAgain = true;
104            dc.destroy();
105            System.gc();
106
107            if (setup.getParameter("debug").equalsIgnoreCase("true")) {
108                System.out.println("Mensagem de retorno: " + answer[1].trim());
109            }
110
111            // Mostra mensagem de erro para o usuário
112            DialogBuilder.showMessageDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this), answer[1].trim(), this.setup);
113            Thread.yield();
114        }
115
116        return tryAgain;
117    }
118
119    private boolean parseHandleCertificateResponse(String certificate){
120       
121        // Envia certificado
122       
123        JSObject document = (JSObject) JSObject.getWindow(this).getMember("document");
124        JSObject certificateForm = (JSObject) document.getMember("certificateForm");
125        JSObject certificateField = (JSObject) certificateForm.getMember("certificado");
126        certificateField.setMember("value", certificate);
127
128        // submit e cai fora
129        certificateForm.call("submit", null);
130       
131        dc.destroy();
132        System.gc();
133        Thread.yield();
134
135        return false;
136    }
137
138    /* (non-Javadoc)
139     * @see java.applet.Applet#start()
140     */
141    @Override
142    public void start() {
143        super.start();
144
145        int useCertificate = DigitalCertificate.KEYSTORE_NOT_DETECTED;
146        boolean tryAgain = true;
147
148        do {
149
150            // Cria uma instância de DigitalCertificate e a inicializa
151            // Aqui pega document base e verifica em que aplicação estamos.
152
153            this.dc = new DigitalCertificate(this.getDocumentBase(), setup);
154            useCertificate = dc.init();
155
156            try {
157
158                String redirect = "";
159
160                // Testa em qual aplicação estamos.
161                URL documentURL = this.getDocumentBase();
162
163                if (documentURL.getPath().matches(".*login.php$")){
164                    redirect = this.getCodeBase().getProtocol() + "://" + this.getCodeBase().getHost()
165                        + ":" + this.getCodeBase().getPort() + "/login.php";
166                }
167                else {
168                    redirect = this.getCodeBase().getProtocol() + "://" + this.getCodeBase().getHost()
169                        + ":" + this.getCodeBase().getPort() + "/preferences/index.php";
170                }
171
172                switch (useCertificate) {
173                    case DigitalCertificate.KEYSTORE_DETECTED:
174                        // Mostra PinNeedeDialog.
175                        String pin = DialogBuilder.showPinDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this), this.setup);
176                       
177                        if (pin != null) {
178                            dc.openKeyStore(pin.toCharArray());
179                            if (documentURL.getPath().matches(".*login.php$")){
180                                tryAgain = parseVercert(dc.getCredentials(pin, new URL(this.getCodeBase().getProtocol()+"://" +
181                                    this.getCodeBase().getHost() + ":" + this.getCodeBase().getPort() +
182                                    "/security/vercert.php")));
183                            }
184                            else {
185                                tryAgain = parseHandleCertificateResponse(dc.getPEMCertificate());
186                            }
187
188                        } else {
189
190                            // TODO: Notifica usuário
191                            tryAgain = false;
192                            try {
193                                this.getAppletContext().showDocument(new URL(redirect));
194                            } catch (MalformedURLException e) {
195                                // TODO Bloco catch gerado automaticamente
196                                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
197                                    e.printStackTrace();
198                                }
199                            }
200                        }
201
202                        break;
203                    default:
204
205                        // TODO: notifica usuário que token não foi encontrado
206                        // ou repositório de chaves públicas não foi configurado.
207                        // Tentar carregar token/keystore novamente? / Logon sem certificado digital?
208
209                        tryAgain = false;
210                        if (setup.getParameter("debug").equalsIgnoreCase("true")) {
211                            System.out.println("não achou token");
212                        }
213
214                        dc.destroy();
215                        System.gc();
216
217                        try {
218                            this.getAppletContext().showDocument(new URL(redirect));
219                        } catch (MalformedURLException e) {
220                            // TODO Bloco catch gerado automaticamente
221                            if (setup.getParameter("debug").equalsIgnoreCase("true")) {
222                                e.printStackTrace();
223                            }
224                        }
225                }
226
227            } catch (SSLHandshakeException e) {
228                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
229                    e.printStackTrace();
230                }
231                dc.destroy();
232                System.gc();
233                DialogBuilder.showMessageDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this),
234                        this.setup.getLang("ExpressoCertLoginMessages", "LoginApplet001"), this.setup);
235
236                Thread.yield();
237
238                tryAgain = true;
239            } catch (HttpException e) {
240                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
241                    e.printStackTrace();
242                }
243
244                tryAgain = true;
245                Thread.yield();
246            } catch (GeneralSecurityException e) {
247                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
248                    e.printStackTrace();
249                }
250
251                DialogBuilder.showMessageDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this),
252                        this.setup.getLang("ExpressoCertLoginMessages", "LoginApplet002"), this.setup);
253
254                Thread.yield();
255                tryAgain = true;
256            } catch (IOException e) {
257                dc.destroy();
258                System.gc();
259
260                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
261                    e.printStackTrace();
262                }
263
264                Throwable cause = null;
265                if ((cause = e.getCause()) != null) {
266                    if (cause instanceof javax.security.auth.login.LoginException) {
267                        DialogBuilder.showMessageDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this), this.setup.getLang("ExpressoCertLoginMessages", "LoginApplet003"), this.setup);
268                    } else {
269                        if (setup.getParameter("debug").equalsIgnoreCase("true")) {
270                            System.out.println("Exception lançada: " + cause.getClass().getCanonicalName());
271                        }
272                    }
273                } else {
274                    if (e instanceof java.net.ConnectException) {
275                        DialogBuilder.showMessageDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this),
276                                this.setup.getLang("ExpressoCertLoginMessages", "LoginApplet004"), this.setup);
277                    } else {
278                        if (setup.getParameter("debug").equalsIgnoreCase("true")) {
279                            System.out.println("Exception lançada: " + e.getClass().getCanonicalName());
280                        }
281                    }
282                }
283
284                Thread.yield();
285                tryAgain = true;
286            } catch (ProviderException e) {
287
288                dc.destroy();
289                System.gc();
290
291                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
292                    e.printStackTrace();
293                }
294
295                int resultado = DialogBuilder.showConfirmDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this),
296                        //"Deseja tentar carregá-lo novamente?",
297                        this.setup.getLang("ExpressoCertLoginMessages", "LoginApplet005"),
298                        JOptionPane.QUESTION_MESSAGE,
299                        JOptionPane.OK_CANCEL_OPTION, this.setup);
300
301                if (resultado == JOptionPane.OK_OPTION) {
302                    tryAgain = true;
303                } else {
304                    tryAgain = false;
305                }
306
307                Thread.yield();
308            }
309
310        } while (tryAgain);
311
312    }
313
314    /**
315     * Destrói a Applet, executando códigos para desregistrar tokens, keystores, etc.
316     */
317    @Override
318    public void stop() {
319        //super.destroy();
320        if (setup.getParameter("debug").equalsIgnoreCase("true")) {
321            System.out.println("Finalizando Applet de Login!");
322        }
323
324        this.dc.destroy();
325        this.dc = null;
326        System.gc();
327    }
328}
Note: See TracBrowser for help on using the repository browser.