Problemas ao logar usuário através do método POST. Só consigo através de uma página HTML

Olá. Estou desenvolvendo uma aplicação que disponibilizará acesso a clientes J2ME. O servidor dessa aplicação usa o framework Spring Security para autenticação e gerenciamento de sessão dos usuários. Porém, só estou conseguindo logar na aplicação utilizando uma página HTML e fazendo uma requisição via POST. Eu acredito que o processo seja o mesmo, tanto numa página HTML como enviando uma requisição através do cliente J2ME. Logo, suspeito que estou fazendo algo errado na aplicação móvel.

Eu não pretendo utilizar cookies, por isso desabilitei no navegador. Deste modo o spring já fornece o jsessionid na própria URL. Apenas pra elucidar, no servidor eu configurei para que uma servlet seja processada quando o usuário não estiver logado e essa servlet apenas exibe “Acesso Negado”. Logo, toda vez que eu acesso algum serviço da minha aplicação e não estou logado sou redirecionado para um link como esse e recebo “Acesso Negado”:

http://localhost:porta/aplicacao/login;jsessionid=42093420934023

Lógico que a jsessionid é sempre diferente. Pra realizar o teste no navegador, utilizo a seguinte página (configuro com a jsession id obtida anteriormente):

<html>
   <head>
      <title>Teste de acesso ao servidor</title>
   </head>
   <body>
      <form action="http://localhost:8084/Server/j_spring_security_check;jsessionid=42093420934023" method="POST">
         Nome: <input type="text" name="j_username"><br/>
         Senha: <input type="password" name="j_password"><br/>
         <input type="submit" value="Go!">
      </form>
   </body>
</html>

Após isto, eu sou redirecionado para a página em que tentei acessar inicialmente, porém agora logado e com um novo jsessionid. A partir deste novo jsessionid eu consigo, normalmente, acessar todos os outros serviços da aplicação.

O problema é que na aplicação J2ME, após eu “realizar login” (acho que isso não está acontecendo), minha aplicação continua indo pra servlet que retorna “Acesso Negado”, ou seja, como se não tivesse logado. Meio que no desespero, criei essa classe que faz tudo sequencialmente, apenas pra fazer funcionar esse caso hipotético. Lógico que não é a que irei usar na aplicação, mas para os testes ela já é suficiente:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.unesc.kiron;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;

/**
 * Classe simples para testar conexao j2me
 * 
 * @author wagner
 */
public class ConexaoServidorXML implements Runnable {

    private String urlServer = "http://localhost:8084/Server/";
    private String urlLogin = "j_spring_security_check";
    private HttpConnection connection = null;
    private String urlCorrente = null;
    private String urlInicial = null;
    private String username,  password;

    /* A URL inicial não é inteira, apenas especifica qual serviço vou usar. */
    public ConexaoServidorXML(String urlInicial, String username, String password) {
        this.urlInicial = urlInicial;
        this.username = username;
        this.password = password;
    }

    /* Realiza conexao */
    public void run() {
        try {
            String dados = "j_username=" + username + "&j_password=" + password;
            connection = (HttpConnection) Connector.open(urlServer + urlInicial);
            System.out.println(urlServer + urlInicial);
            connection.setRequestMethod(HttpConnection.POST);
            connection.setRequestProperty("If-Modified-Since", "28 Jul 2008 11:51:00 GMT");
            connection.setRequestProperty("User-Agent", "Profile/MIDP-2.0 Configuration/CLDC-1.1");
            connection.setRequestProperty("Content-Language", "pt-BR");
            connection.setRequestProperty("Custom-Property", "MyCustomProperty/1.0; AnotherProperty/debug_0.1");
            connection.setRequestProperty("Content-Length", Integer.toString(dados.getBytes().length));
            if (connection.getResponseCode() == 302) {
                System.out.println("Arrumar url pra logar");
                /* Recebendo jsessionid */
                String jsessionid = getJSessionId(connection.getHeaderField("Location"));
                connection.close();
                connection = (HttpConnection) Connector.open(urlServer + urlLogin + ';' + jsessionid);
                connection.setRequestMethod(HttpConnection.POST);
                
                OutputStream output = connection.openOutputStream();
                output.write(dados.getBytes());
                output.flush();
                output.close();

                if (connection.getResponseCode() == 302) {
                    //Nova URL. Aqui ja deveria estar rebendo a URL com o jsessionid logado e acessar os servicos anteriores 
                    String new_uri = connection.getHeaderField("Location");
                    System.out.println(new_uri);
                    connection.close();
                    connection = (HttpConnection) Connector.open(new_uri);
                    connection.setRequestMethod(HttpConnection.POST);
                    System.out.println("Iniciar leitura");
                    InputStream input = connection.openInputStream();
                    StringBuffer buf = new StringBuffer();
                    int c;

                    while ((c = input.read()) != -1) {
                        buf.append((char) c);
                    }
                    System.out.println(buf.toString());
                    input.close();
                }
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                connection.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    public String getJSessionId(String str) {
        for (int i = 0; i < str.length(); ++i) {
            if (str.charAt(i) == ';') {
                return str.substring(i + 1);
            }
        }
        return null;
    }
}

O problema é que só recebo “Acesso Negado”. Estou realizando algum procedimento errado para enviar os parâmetros j_username e j_password? Esses redirecionamentos (usando a resposta 302 do servidor http) estão corretos? Alguém tem idéia do que possa estar acontecendo?

Obrigado pela atenção!

Tenta colocar um connection.setRequestProperty(“Content-Disposition”, “form-data”);

[quote=WTGA]Tenta colocar um connection.setRequestProperty(“Content-Disposition”, “form-data”);
[/quote]

Olá, coloquei, mas continuou igual. De qualquer maneira, muito obrigado, se tiver mais alguma dica, agradeço!

[quote=wagnerfrancisco][quote=WTGA]Tenta colocar um connection.setRequestProperty(“Content-Disposition”, “form-data”);
[/quote]

Olá, coloquei, mas continuou igual. De qualquer maneira, muito obrigado, se tiver mais alguma dica, agradeço![/quote]

O header “Location” te fornece o session id ? Não sabia que vinha por este header…

Seria a coisa a se suspeitar para o acesso estar sendo negado, creio.

[quote=boone][quote=wagnerfrancisco][quote=WTGA]Tenta colocar um connection.setRequestProperty(“Content-Disposition”, “form-data”);
[/quote]

Olá, coloquei, mas continuou igual. De qualquer maneira, muito obrigado, se tiver mais alguma dica, agradeço![/quote]

O header “Location” te fornece o session id ? Não sabia que vinha por este header…

Seria a coisa a se suspeitar para o acesso estar sendo negado, creio.[/quote]

Olá. O header “Location” me fornece o endereço retornado pelo servidor (pelo que percebi). Como não estou utilizando cookies, o servidor já devolve o jsessionid escrito na própria URL, por isso simplesmente separei o que vinha após o ‘;’, que era a jsessionid. Há algum problema nesse procedimento? Existe algum outro header que devolva apenas o jsessionid?

Obrigado pela atenção.

Acabei de realizar testes enviando os parâmetros j_username e j_password na própria URL e, pasmem, funcionou, mesmo eu tendo configurado a conexão como POST.

Alguém tem alguma idéia do porque disso?

Mais uma vez, obrigado.

Ocorre que quando você envia os parâmetros incialmente pelo POST, o servidor te redireciona para outra URL, a URL real de login. Nesse redirecionamento se perdem as informações de POST. No entanto, se você colcoar os parâmetros na própria URL, com o redirecionamento os parâmetros não se perdem, pois toda a URL é redirecionada. Assim, quando a URL redirecionada é executada, ela consegue ver os parâmetros de usuário e senha.

Sugestão para caso você queira usar POST: Pegar a URL real de redirecionamento, a URL real para onde é feito o LOGIN.

Abraço

[quote=npereirajr]Ocorre que quando você envia os parâmetros incialmente pelo POST, o servidor te redireciona para outra URL, a URL real de login. Nesse redirecionamento se perdem as informações de POST. No entanto, se você colcoar os parâmetros na própria URL, com o redirecionamento os parâmetros não se perdem, pois toda a URL é redirecionada. Assim, quando a URL redirecionada é executada, ela consegue ver os parâmetros de usuário e senha.

Sugestão para caso você queira usar POST: Pegar a URL real de redirecionamento, a URL real para onde é feito o LOGIN.

Abraço[/quote]

Está meio confuso pra mim ainda. Eu entendi o que você disse, mas acho que é o que estou fazendo. Repare que quando eu sou redirecionado na aplicação, eu acesso o servidor novamente usando a string “urlLogin”. Essa url é a mesma que eu uso pra logar através meu código HTML. E ainda nesse acesso, eu faço a transferência de dados (usuário e senha). Talvez quando eu acesse ele já redirecione para o endereço de acesso negado, e eu não tenha tempo de enviar os parâmetros username e password, mas aí seria complicado fazer o que eu quero com POST.

Enfim, espero ter conseguido ser claro. Obrigado!

Não é você quem faz o redirect, é o server. Você não vê nada.