JAAS alguém usa?

47 respostas
J

Gente, eu precisei usar JAAS pra certificação … achei super util

mas eu nao aprendi como fazer para ele procurar os usuarios e senhas em um banco de dados …

alguem tem um tutorial que mostre isso?

to achando muit oesquisito pq os tutoriais na net, param na configuração do web.xml ou ensinam a configurar um arquivo .properties :S no servidor
será q todo mundo usa outra coisa? rsrs vcs usam filtros? fazer na mão? nun é arriscado? tem outro framework bom pra segurança?

tudo o q eu leio, mete o pau em quem não usa a JAAS, mas ninguem ensina como faz pra integrar com o banco de dados :frowning:

alguém dah uma luz pra eu? rsrs

brigadoo

47 Respostas

F

Já deu uma olhada no tutorial de JAAS postado aqui no GUJ?

R

com uma rapida busca da palavra JAAS no google encontramos o seguinte resultado:

http://www.jeveaux.com/blog/2009/autenticacao-e-autorizacao-jaas-com-jdbc-realm/

abrasssss

G

Há muita documentação sobre jaas na internet. Esse post do jeveaux que o Renan indicou é muito bom.

Jaas é bem seguro, e o que eu mais gosto nele é o fato de você poder plugar algum método de autenticação que você quiser sem alterar nada no seu código. Basta conectar o novo módulo e feito. Além disso a autorização é propagada ao módulo EJB, muito útil para você escrever pouco código. Ou seja, você apenas anota os beans e ele controla o acesso.

Com o Jaas não precisa filtro algum, ele mesmo já controla as roles/acessos e afins, exibido as páginas de acesso negado e/ou telas de login.

Faz alguns anos que o Jaas não sobre nenhuma alteração, e pena que no Java7 não tem nada previsto para ele.

Abraços

R

Bom dia… em nossa arquitetura utilizamos o JAAS, inclusive com acesso ao banco e autenticação no AD.

Em resumo fizemos assim:

Criamos um LoginModule, e este realiza uma autenticação no AD, blz… as Roles são populadas apartir de uma query no banco de dados.

Para o seu caso, basta fazer a busca dos Principal no banco e suas respectivas Roles. Isso tudo deve ser codificado no LoginModule.

Alguns detalhes são:

No LoginModule faça um extends do DatabaseServerLoginModule.

Parte do initialize…

public void initialize(Subject subject, CallbackHandler callbackHandler,
			Map sharedState, Map options) {

		super.initialize(subject, callbackHandler, sharedState, options);
		this.subject = subject;
		this.callbackHandler = callbackHandler;
		this.sharedState = sharedState;

                // estou utilizando um ds.
		dsJndiName = (String) options.get("dsJndiName");

                // veja a query para o acesso o banco
		rolesQuery = "SELECT g.gruponome FROM lmod_usuario_grupo ug, lmod_usuario u, lmod_grupo g WHERE ug.usuario_usuarioid = u.usuarioid AND ug.grupo_grupoid = g.grupoid AND u.usuariochave=?";

	}

feito isso… fazemos uma autenticação no AD via LDAP… autenticando o usuário falta criar as autorizações… As Roles

Coisa básica, com Connection, PreparedStatement, etc…

protected Group[] getRoleSets() throws LoginException {

		Group[] groups = { new SimpleGroup("Roles") };
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			InitialContext ctx = new InitialContext();
			DataSource ds = (DataSource) ctx.lookup(dsJndiName);
			conn = ds.getConnection();

			ps = conn.prepareStatement(rolesQuery);
			ps.setString(1, getIdentity().getName());
			rs = ps.executeQuery();
			
			while (rs.next()) {
				String roleName = rs.getString(1);
				log.info(">>>>" + roleName);
				SimplePrincipal role = new SimplePrincipal(roleName);
				groups[0].addMember(role);				
			}
	
		} catch (Exception e) {
			e.printStackTrace();
		} finally {			
			try {
				rs.close();
				ps.close();
				conn.close();
			} catch (Exception e) {
				log.error("Error ao fechar as transações" + e.getMessage());
			}	
			
		}
		SimplePrincipal role = new SimplePrincipal("logado");
		groups[0].addMember(role);

		return groups;
	}

Bom … basicamente é isso… se tiver algum problema mais específico me avise !!!

Estou com este um problema, extra o JAAS
http://www.guj.com.br/posts/list/142275.java

Abraços !!!

t+

R

unica deficiencia que vejo no JAAS é o fato de não conseuigr criar Roles dinamicamente, pois é necessário alterar o web.xml

abrassss

R

Então… renanreismartins ;

Este foi o principal problema que tivemos. Resolvemos colocando a Roles no Banco de Dados… assim o usuário faz a AUTENTICAÇÃO no AD e a lista de Roles, vem do banco, ou seja as AUTORIZAÇÕES.

Com isso temos as Roles dinamicas.

t+

R

rodrigo_ctba opaaaaaaaa, n acredito que vc fez isso, to atras disso A MUITO TEMPO, perai parcero vamo conversa rs…

1o qq significa AD ?

2o como fica com as roles no banco ? pq ateh onde cheguei, realmente eh necessario que o web.xml tenha os caminhos que podem ser acessados por um determinado “grupo” de usuarios…

nao sei se fui claro mas: como colocar quais caminhos podem ser acessados, no banco ao inves de no web.xml ?

abraasssss

R

oi… renanreismartins

AD = Active Directory Windows Server, é o servidor onde o Windows autentica os usuários do sistema. Basicamente utilizando LDAP.

Então… na verdade ainda funciona assim, pois não teria como modificar o arquivo web.xml, certo !!!

Assim, resolvemos da seguinte forma… no xml temos uma Roles de acesso ou seja uma roles que o usuário deve ter
para acessar a aplicação…blz ?! coisa básica… esta Role esta cadastrada no Banco !!! :wink:

Feito isso, temos um PhaseListener do JSF ou como queira um Filter. Partindo do principio que as Roles, estão no HttpSession do usuário, podemos testar o seu acesso com um PhaseListener, com JSF funciona muiiiito bem e não temos queda na performance da aplicação.

Desta forma qual a vantagem? Se um usuário quizer ter acesso ao sistema… seja qual for, primeiramente ele deve ter aquela Role de permissão ao sistema !!! E depois internamente, fazemos qualquer negócio !! Inclusive com o MyFaces é possível ocultar componentes (botões, labes, etc)…

Caso, seu projeto tenha algumas pastas que determinados usuários poderão acessar, mesmo estando autenticado isso fica no web.xml, mas a roles fica cadastrada no banco e esta atribuida ao usuário.

Isso, tudo deve ficar especificado no documento de segurança do sistema, pois são definições que podem impactar na operação do mesmo.

Bom, mais ou menos é isso !!!

t+

R

valeu rodrigo_ctba … entendi perfeitamente como fazem, devido sua implementação de um Filter ou PhaseListener, seu JAAS está servindo apenas para o usuario nao acesse algumas pastas mesmo autenticado.

Ou seja, nao existe a criaçao de roles dinamicamente, este eh meu problema.

Preciso definir dinamicamente uma role X e definir tambem dinamicamente quais recursos essa role pode acessar…

ouvi falar de um tal de jguard que é desenvolvido em cima do jaas, mas nao conheço nada vou dar uma olhada, caso ele resolva o problema posto aqui… ps: isso vai demorar rs

abrasssss

J

eita que o tópico fez sucesso ahuahau

eu to a uns 3 dias tentando entender legal o artigo q tah no guj rsrs tah certo q eu nun dediquei muito tempo a isso rsrs, mas eu acho, na minha humilde opinião de pouco entendedor de JAAS, que deve haver uma implementaçao mais simples …

o artigo q o amigo passou sobre autenticação e jdbc achei legal pois é simples e bem explicado http://www.jeveaux.com/blog/2009/autenticacao-e-autorizacao-jaas-com-jdbc-realm/

mas o ruim é que nao mostra como trabalhar com criptografia e nem com form security , só usa o basic que ao meu ver é inviavel … tá perfeito nada de preparestatments nem nada, deixa tudo por conta do container( e tenho certeza q qm fez o container manja MUITOOO mais de java q eu ahuahua) só faltava integrar akilo com o formulario e criptografia

to procurando outros artigos ainda … mas pelo visto , terei que queimar um pouco a cachola e tentar fazer uma junção desses artigos aí …

queria fazer uma coisa com o minimo de descencia rsrs Autenticação baseada em formulario, Autorização no web.xml , criptografia e consultas no banco sem que eu precise fazer esforço rs ( to querende demais né )

consulta no banco de autorização e autenticação sem eu precisar botar a mao em codigo rsrs jah aborda perfeitamente no artigo :
http://www.jeveaux.com/blog/2009/autenticacao-e-autorizacao-jaas-com-jdbc-realm/

agora só falta eu saber com ointegrar isso ai com formulario e criptografia

falow gente :slight_smile:

R

javando mto simples man…

crie um form no atributo action coloque j_security_check
e dentro deste form adicione dois inputs com os nomes: j_username e j_password, para login e senha, respetivamente

ex:

<form action="j_security_check" method="post" id="form1" name="form1">
  <input name="j_username" type="text" />
   <input name="j_password" type="password" class="edit" />
</form>

abrasssss

J

sim ué rsrsrsrs

isso eu já conhecia, mas automaticamente ele já reconhece pra onde ele vai enviar o login e a senha dentro da aplicação?

nao preciso criar nenhum tipo de handler pra isso ai?

G

javando, o JAAS faz tudo isso que você quer. Só que você precisa entender melhor o conceito.

Você pode usar tanto basic como digest. Ambas aparecem aquele dialog para digitar user/senha. Porém o basic é senha plana, já o digest trafega a senha criptografada. Você pode usar o form também da mesma forma que o basic e digest, basta alterar no web.xml para form e definir os jsps de login e erro de login.

Quando ao acesso a banco, o JAAS permite acesso no banco de dados com ou sem critografica, além de acesso a senhas em arquivos, ldap... e alguns mais. Tudo muito configurável.

Abaixo um exemplo do meu formulário de login via JAAS. Comentei para você entender.

web.xml
<login-config>
	<auth-method>FORM</auth-method> <!-- usa formulario -->
	<realm-name>esim-jaas-realm</realm-name>
	<form-login-config>
		<form-login-page>/WEB-INF/jspx/form-login.jspx</form-login-page> <!-- pagina de login -->
		<form-error-page>/WEB-INF/jspx/form-login.jspx?error=true</form-error-page> <!-- quando der erro vem para cá -->
	</form-login-config>
</login-config>

<security-constraint>
	<web-resource-collection>
		<url-pattern>/*</url-pattern> <!-- todos links são seguros -->
		<http-method>GET</http-method>
		<http-method>POST</http-method>
	</web-resource-collection>
	
	<auth-constraint> <!-- minhas roles -->
		<role-name>ROLE_ADMIN</role-name>
		<role-name>ROLE_SINGLEUSER</role-name>
		<role-name>ROLE_OPERATOR</role-name>
	</auth-constraint>
	
	<user-data-constraint>
		<transport-guarantee>CONFIDENTIAL</transport-guarantee> <!-- acesso somente via HTTPS -->
	</user-data-constraint>
</security-constraint>
form-login.jspx
<form method="post" action="j_security_check">
	Username <input type="text" name="j_username" /> <br />
	Password <input type="password" name="j_password" /><br />
	<input type="submit" />
</form>

Arquivo de configuração do JAAS no glassfish

<auth-realm classname="com.sun.enterprise.security.auth.realm.jdbc.JDBCRealm" name="esim-jaas-realm">
  <property name="user-name-column" value="userid"/>
  <property name="digest-algorithm" value="md5"/> <!-- criptografia de senha md5 -->
  <property name="password-column" value="password"/>
  <property name="group-name-column" value="groupid"/>
  <property name="datasource-jndi" value="jdbc/esimOracleDS"/><!-- meu datasource -->
  <property name="user-table" value="jaas_usertable"/>
  <property name="group-table" value="jaas_grouptable"/>
  <property name="jaas-context" value="jdbcRealm"/>
</auth-realm>

Ou seja, autenticação via JAAS pelo método form, com página personalizada, senhas criptografadas, e ainda mantenho integração entre meu módulo web e meu módulo EJB. Quando a session do usuário morre, o JAAS intercepta a requisição, mostra a tela de login, e após login ok, volta para a tela que o usuário estava.

Creio que meu exemplo pode te ajudar, e como você está usando tomcat, você terá apenas que adaptar o XML do auth-realm.

Quaisquer dúvidas, pergunte. Abraços :thumbup:

G

javando:
sim ué rsrsrsrs

isso eu já conhecia, mas automaticamente ele já reconhece pra onde ele vai enviar o login e a senha dentro da aplicação?

nao preciso criar nenhum tipo de handler pra isso ai?

Quem faz o “handler” é o container, pela url j_security_check. Ele intercepta, processa, e se der sucesso no login, redireciona para o sistema.

J

OPA … brigadão :slight_smile:

só faltava mesmo saber como era a configuração do real no tomcat :slight_smile: … agora nun falta mais hehehe

http://tomcat.apache.org/tomcat-5.5-doc/realm-howto.html#What%20is%20a%20Realm?
nesse artigo faltava mostrar qual era a propriedade que eu devia usar para definir o tipo de criptografia …

nesse artigo tem:
http://tomcat.apache.org/tomcat-3.3-doc/JDBCRealm-howto.html

seria a propriedade digest:

digest The algorithm used for digest passwords or “No” for plain passwords, the values can be “MD5”, “MD2”, “SHA”, etc… (Optional)

já entendi quase tudo o que precisa rsrs

só uma coisinha …

quando eu for cadastrar um novo usuário, como é que eu faço pra cadastrar no banco a senha criptografada? :slight_smile:

de preferencia sem usar uma classe nativa do tomcat ( pq ele fornece uma classe com um metodo para encriptar), pq se eu mudar o container, teria que editar o codigo fonte…

brigadão mesmo :slight_smile:

eita gente inteligente :slight_smile: hehehe

R

renanreismartins , é assim, apenas uma roles é usada para permitir o acesso do usuário no sistema as outras são utilizadas dentro do sistema para permitir acesso a qualquer tipo de recurso, ou seja desde simples páginas e seus componentes até sessionbeans.

Com o JSF, temos um objeto UIViewRoot que é a pagina do usuário, dentro desse objeto podemos navegar em componentes, labels e botões, validando se o usuário tem permissão para que tal componente seja rendenizado.

Todas as roles vem do banco e esta associado a um usuário, ou seja se eu tirar uma role, em pleno vôo o sistema vai bloquear.

Quanto ao definir um recurso X, você pode associar o X a uma ou mais roles…

Em nossa empresa, temos diversos sistemas em J2EE… e todos utilizam o LoginModule e a implementação que gerencia as roles e usuários.

t+

R

javando otimo postar as referencias

cara para criptografar a senha vc pode usar uma algoritmo de cript. e salvar no banco a senha ja criptografada

segue um exemplo:

public class Util {

	public static String encrypt(String senha) {
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(senha.getBytes());
			byte[] hash = md.digest();
			StringBuffer hexString = new StringBuffer();
			for(int i = 0; i &lt; hash.length; i++) {
				if((0xff & hash[i]) &lt; 0x10)
					hexString.append("0" + Integer.toHexString((0xFF & hash[i])));
				else
					hexString.append(Integer.toHexString(0xFF & hash[i]));
			}
			senha = hexString.toString();
		} catch (Exception nsae) {
			nsae.printStackTrace();
		}
		return senha;
	}

	public static void main(String[] args) {
		System.out.println(Util.encrypt("123"));
	}

}

obs: esse codigo n eh meu, mas é ctza que gera uma senha em md5.

rodrigo_ctba entendi velho…

isso soh pode ser feito via web.xml logo nao eh dinamico ;D

abrassss

G

javando:
só uma coisinha …

quando eu for cadastrar um novo usuário, como é que eu faço pra cadastrar no banco a senha criptografada? :slight_smile:

de preferencia sem usar uma classe nativa do tomcat ( pq ele fornece uma classe com um metodo para encriptar), pq se eu mudar o container, teria que editar o codigo fonte…

Eu uso como criptografia o MD5, então uso o DigestUtils.md5Hex() que vem no commons-codec, projeto da Apache. Ou seja, quando eu cadastro o usuário eu já gravo a senha com o md5.

Ou seja, na minha view jaas_usertable há dois campos: email do usuário e senha em MD5. Uso o email como login.

Caso você não queira usar o commons-codec você pode fazer a criptografia do MD5 na mão ou até mesmo via comando SQL.

J

renanreismartins

brigadão hein hehe

agora com todas as informações na mão … vou fazer aki a aplicação :slight_smile:

qualquer duvida voltarei hehe

se funcionar volto tambem pra dar o result rsrs

brigadãooooo :slight_smile:

R

garcia-jj detalhe, no seu caso, email como login, essa coluna eh sua chave primaria ?

abrassss

G

renanreismartins:
garcia-jj detalhe, no seu caso, email como login, essa coluna eh sua chave primaria ?

abrassss

Eu criei uma view baseada na minha tabela de usuário. A chave primária é um long/number, o campo email é uma unique-key, por isso posso usar tranquilamente como chave de login, pois nunca terão dois usuários com mesmo email. É complicado você fazer foreign-key com email, pois além de ter varchar como fk, você não consegue alterar mais o email do usuário.

Na verdade as duas tabelas que o jaas precisa acessar são views. A tabela de usuário do meu sistema é bem mais complexa. Então optei por fazer a view e deixar apenas o que o jaas precisa acessar.

Abraços

R

garcia-jj aki uso um jdbcrealm personalizado, estamos utilizando o glassfish…

mas view… otima alternativa hein! valeu demais, mto obrigado

abrasss a tds…

G

renanreismartins:
garcia-jj aki uso um jdbcrealm personalizado, estamos utilizando o glassfish…

mas view… otima alternativa hein! valeu demais, mto obrigado

abrasss a tds…

Hmm, entendi. Uma coisa que eu tentei de todas as formas é criar um realm personalizado que fizesse a consulta nos meus EJBs e ao invés de retornar um Principal do Glassfish retornasse um meu, porém não consegui. Você usou o Principal do glassfish?

R

entao garcia_jj nao usei o do glassfish pelo seguinte motivo:

como nao tive a ideia de utilizar uma view, com o realm do glassfish, minha coluna de identificação de usuario teria de ser a chave primaria, oque seria “inaceitavel”.

entao nas configurações do servidor, ao inves de escolhermos a nativa, colocamos o pacote com a implementação personalizada:

org.nbcommunity.glassfish.jdbcAuthModule.JdbcRealm

desenvolvido pelo Edson Carlos Ericksson Richter. La alteramos as sqls para o nosso caso.

obs: feito isso vc tem que colocar seu jar dentro da pasta lib\addons na raiz da instalaçao do glassfish, bem como colocar o caminho completo para o jar no Classpath Suffix dentro do menu Application Server, aba JVM Settings e sub aba Path Settings.

mas se no seu caso deu certo apenas acessando uma view, acho bem mais viavel, vou até estudar a possibilidade. Posso contar com vc caso decida implementar assim ?

eh isso… qq coisa chamae

abrassssss

G

Sim, conte comigo :slight_smile:

Vou fazer mais uns testes aqui, e conversamos. Abraços, e obrigado.

J

Gente, tem um errinhoaki no tomcat …

está assim o meu META-INF/context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context>
 <Resource 
 	name="jdbc/autenticacao" 	
 	auth="Container"
 	type="javax.sql.DataSource"
 	maxActive="100" 
 	maxIdle="30" 
 	maxWait="10000"
 	username="root" 
 	password="root" 
 	driverClassName="com.mysql.jdbc.Driver"
 	url="jdbc:mysql://localhost:3306/autentica?autoReconnect=true"/>





<Realm className="org.apache.catalina.realm.DataSourceRealm" debug="99"
   name="jdbc-realm-autenticacao"
   dataSourceName="jdbc/autenticacao"
   userTable="usuario" 
   userNameCol="id_usuario" 
   userCredCol="nm_senha"
   userRoleTable="grupo"
   roleNameCol="id_grupo"
   digest="SHA-1"
   />


</Context>

e eu faço referencia a ele no meu web.xml assim:

......

<resource-ref>
      <res-ref-name>jdbc/autenticacao</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
  </resource-ref>
  <login-config>
    <auth-method>DIGEST</auth-method>
    <realm-name>jdbc-realm-autenticacao</realm-name>
  </login-config>

.....

mas quando aparece a caixa pra autenticação e eu tento entrar no sistema … dá erro:

SEVERE: Exception performing authentication

javax.naming.NameNotFoundException: Name jdbc is not bound in this Context

at org.apache.naming.NamingContext.lookup(NamingContext.java:770)

at org.apache.naming.NamingContext.lookup(NamingContext.java:153)

at org.apache.catalina.realm.DataSourceRealm.open(DataSourceRealm.java:403)

at org.apache.catalina.realm.DataSourceRealm.getPassword(DataSourceRealm.java:429)

at org.apache.catalina.realm.RealmBase.getDigest(RealmBase.java:1161)

at org.apache.catalina.realm.RealmBase.authenticate(RealmBase.java:367)

at org.apache.catalina.authenticator.DigestAuthenticator.findPrincipal(DigestAuthenticator.java:283)

at org.apache.catalina.authenticator.DigestAuthenticator.authenticate(DigestAuthenticator.java:176)

at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:491)

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)

at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)

at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)

at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)

at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)

at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)

at java.lang.Thread.run(Unknown Source)

:S

o pior, é que se eu acesso a base de dados via jstl … funciona dormal …

o código abaixo funciona perfeitamente…

<sql:query var="rs" dataSource="jdbc/autenticacao" >
SELECT id_usuario, nm_usuario FROM usuario order by 1 desc
</sql:query>

<table>
<c:forEach var="row" items="${rs.rows}">
<tr>
<td>${row.id_usuario}</td>
<td>${row.nm_usuario}</td>
</tr>
</c:forEach>
</table>

idéias?

valeu :slight_smile:

G

Sempre culpa do tomcat, grrrrrrr.

Você precisa fazer um link do resource para ele mesmo, senão o tomcat se perde ao buscar a arvore.

<ResourceLink name="jdbc/autenticacao" global="jdbc/autenticacao" type="javax.sql.DataSource" />
J

[quote=garcia-jj]Sempre culpa do tomcat, grrrrrrr.

Você precisa fazer um link do resource para ele mesmo, senão o tomcat se perde ao buscar a arvore.

<ResourceLink name="jdbc/autenticacao" global="jdbc/autenticacao" type="javax.sql.DataSource" />

Obrigado por responder :slight_smile:

fiz isso aí e não funcionou nao

<?xml version="1.0" encoding="UTF-8"?>
<Context>
 <Resource 
 	name="jdbc/autenticacao" 	
 	auth="Container"
 	type="javax.sql.DataSource"
 	maxActive="100" 
 	maxIdle="30" 
 	maxWait="10000"
 	username="root" 
 	password="root" 
 	driverClassName="com.mysql.jdbc.Driver"
 	url="jdbc:mysql://localhost:3306/autentica?autoReconnect=true"/>


<ResourceLink name="jdbc/autenticacao" global="jdbc/autenticacao" type="javax.sql.DataSource" /> 


<Realm className="org.apache.catalina.realm.DataSourceRealm" debug="99"
   name="jdbc-realm-autenticacao"
   dataSourceName="jdbc/autenticacao"
   userTable="usuario" 
   userNameCol="id_usuario" 
   userCredCol="nm_senha"
   userRoleTable="grupo"
   roleNameCol="id_grupo"
   digest="SHA-1"
   />


</Context>

continua o mesmo erro

G

Hmm, coloque isso então na sua linha 21.

dataSourceName="java:/comp/env/jdbc/autenticacao"

Conforme a documentação em http://tomcat.apache.org/tomcat-6.0-doc/realm-howto.html:

J

garcia-jj:
Hmm, coloque isso então na sua linha 21.

dataSourceName="java:/comp/env/jdbc/autenticacao"

Conforme a documentação em http://tomcat.apache.org/tomcat-6.0-doc/realm-howto.html:

brigado por responder :slight_smile:

Nao funcionou :frowning:

tem outra ideia? …

valeu

G

Foi o mesmo erro? O que aparece agora?

Caso for exatamente o mesmo erro, comente essas configs do JAAS para deixar tua aplicação aberta. Crie um JSP com o conteúdo abaixo:

javax.naming.Context ctx = new javax.naming. InitialContext(); javax.sql.DataSource ds = (javax.sql. DataSource) ctx.lookup("jdbc/autenticacao"); java.sql.Connection conn = ds.getConnection(); out.println(conn);

De ele imprimir algo, está correto. Caso contrário, mostre o erro aqui. Tente também fazer testes alterando o jdbc/autenticacao para java:/comp/env/jdbc/autenticacao.

J

velho … o mesmo erro …

root cause

javax.servlet.ServletException: javax.naming.NameNotFoundException: Name jdbc is not bound in this Context

org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:862)

org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:791)

org.apache.jsp.teste_jsp._jspService(teste_jsp.java:77)

org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)

javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)

org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)

org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)

javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

root cause

javax.naming.NameNotFoundException: Name jdbc is not bound in this Context

org.apache.naming.NamingContext.lookup(NamingContext.java:770)

org.apache.naming.NamingContext.lookup(NamingContext.java:153)

org.apache.naming.SelectorContext.lookup(SelectorContext.java:137)

javax.naming.InitialContext.lookup(Unknown Source)

org.apache.jsp.teste_jsp._jspService(teste_jsp.java:64)

org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)

javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)

org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)

org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)

javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

vou tentar com esses caminhos ai …

J

rapaiz …

eu fiz a seguinte troca:

javax.naming.Context ctx = new javax.naming. InitialContext();  
 javax.sql.DataSource ds = (javax.sql. DataSource) ctx.lookup("java:/comp/env/jdbc/autenticacao");  
 java.sql.Connection conn = ds.getConnection();  
 out.println(conn);

e essa pagina funcionou :slight_smile:

mas continua dando o mesmo erro quando eu tento autenticar …

ai eu tentei trocar no web.xml para:

resource-ref>
      <res-ref-name>java:/comp/env/jdbc/autenticacao</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
  </resource-ref>

mas continua funcionando a pagina e dando o mesmo erro na autenticação

no context fiz o esquema:

<?xml version="1.0" encoding="UTF-8"?>
<Context>
 <Resource 
 	name="jdbc/autenticacao" 	
 	auth="Container"
 	type="javax.sql.DataSource"
 	maxActive="100" 
 	maxIdle="30" 
 	maxWait="10000"
 	username="root" 
 	password="root" 
 	driverClassName="com.mysql.jdbc.Driver"
 	url="jdbc:mysql://localhost:3306/autentica?autoReconnect=true"/>


<ResourceLink name="java:/comp/env/jdbc/autenticacao" global="java:/comp/env/jdbc/autenticacao" type="javax.sql.DataSource" /> 


<Realm className="org.apache.catalina.realm.DataSourceRealm" debug="99"
   name="jdbc-realm-autenticacao"
   
   dataSourceName="java:/comp/env/jdbc/autenticacao"
   userTable="usuario" 
   userNameCol="id_usuario" 
   userCredCol="nm_senha"
   userRoleTable="grupo"
   roleNameCol="id_grupo"
   digest="SHA-1"
   />

troquei tudo kkk

mas o erro persiste

G

Você não precisa declarar nada no web.xml referente ao datasource. Essa idéia de declarar no web.xml é apenas por documentação.

Acho que o correto deve ser isso, sem o java/comp/env no link.

<Resource
    name="jdbc/autenticacao"
    auth="Container"
    type="javax.sql.DataSource"
    maxActive="100"
    maxIdle="30"
    maxWait="10000"
    username="root"
    password="root"
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/autentica?autoReconnect=true" />
  
<ResourceLink name="jdbc/autenticacao" global="jdbc/autenticacao" type="javax.sql.DataSource" />
  
<Realm className="org.apache.catalina.realm.DataSourceRealm" debug="99"
   name="jdbc-realm-autenticacao"
   dataSourceName="java:/comp/env/jdbc/autenticacao"
   userTable="usuario"
   userNameCol="id_usuario"
   userCredCol="nm_senha"
   userRoleTable="grupo"
   roleNameCol="id_grupo"
   digest="SHA-1" />
J

fiz assim e não funcionou :S

i agora josé? rsrs

o mesmo erro

javax.naming.NameNotFoundException: Name java: is not bound in this Context

o que eu acho estranho é … no erro ele só descreve que o nome java: nao foi encontrado …

nao fala q java:/comp/env/jdbc/autenticacao nao foi encontrado …

[[]]ss

J

eita … to avançando …

coloquei no realm a seguinte propriedade…

localDataSource=“true”

e agora nao dá mais erro …

mas tambem nao autentica kkk

eu descriptografei a senha q tava no banco …

e tirei a propriedade de criptografia no realm … aí ele entrou …

mas diz que eu não to autorizado a entrar na pagina (403)

vou olhar melhor as configuração … se nun temnenhum erro no web.xml … mas acho q nun tem nao …

fiquei triste por nao funcionar com a criptografia :S vou tentar com md5 pra ver se vai

J

CONSEGUI ACESSAR !!!

eu desconfiei que o mapeamento que eu estava fazendo no sun-web.xml não estava cunfionando …

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Servlet 2.5//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_2_5-0.dtd">
<sun-web-app >
 
	<security-role-mapping>
	
		<role-name>regra_usuario</role-name>
		<group-name>user</group-name>		
	</security-role-mapping>
 
	<security-role-mapping>
		<role-name>regra_administrador</role-name>
		<group-name>admin2</group-name>
	</security-role-mapping>
 
	<security-role-mapping>
	
		<role-name>regra_todos</role-name>
		<group-name>admin2</group-name>
		<group-name>user</group-name>		
	</security-role-mapping>
	
	</sun-web-app>

[b] 1º entao … lah no web.xml … ao invez de eu colocar regra_administrador como autorizado … eu coloquei diretamente o admin2 no
eu queria saber pq o mapeamento do sun-web.xml nun é reconhecido :S

2º e eu nao consigo fazer com criptografia … só sem :S[/b]

to quase … alguem tem ideiasde como resolver esses dois problemas?

valeu :slight_smile:

F

Pessoal aproveitando o tópico, tenho q fazer uma alteração em um sistema onde o jaas já está implementado…
Ele chama uma procedure oracle para fazer a validação de senha!

Tenho 2 dúvidas:

:?: Uma é que vai ser incluso 2 parametros na proc onde tenho q passar o IP e Host para gravar log (procedure irá fazer isto - varios sistemas chamam esta mesma procedure)!
Voces tem alguma idéia de como fazer isto?
Como solucao porca mas que sei q funciona e pensei em colocar no jsp o j_username como hidden e antes de submeter via javascript eu conteno o ip e host no campo para trafegar para o Login module (o usuário para o jaas estaria algo como flasoft;meuHost;10.1.1.10), lá eu dou um split e chamo a proc normalmente! (porco mas funciona, vcs tem outra idéia?)

:?: Quando o login falha é lancado uma exceção no login module só que “alguma coisa” engole esta exceção e meu Handler exception nao pega ela! Tem como eu manipular as exceções lancadas no login module na jsp ( tipo eu queria na jsp algo como <%= exception.getMensage() %> )

Desde já obrigado pessoal!
Eu tenho q fazer isto até quarta… se eu não conseguir to ferrado! To mais preocupado com a segundo item, pois apesar da primeira solucao ser feia pelo menos é uma solucao! :roll:

Abri um tópico externo com o titulo 2 duvidas com JAAS!

J

Flasoft:
Pessoal aproveitando o tópico, tenho q fazer uma alteração em um sistema onde o jaas já está implementado…
Ele chama uma procedure oracle para fazer a validação de senha!

Tenho 2 dúvidas:

:?: Uma é que vai ser incluso 2 parametros na proc onde tenho q passar o IP e Host para gravar log (procedure irá fazer isto - varios sistemas chamam esta mesma procedure)!
Voces tem alguma idéia de como fazer isto?
Como solucao porca mas que sei q funciona e pensei em colocar no jsp o j_username como hidden e antes de submeter via javascript eu conteno o ip e host no campo para trafegar para o Login module (o usuário para o jaas estaria algo como flasoft;meuHost;10.1.1.10), lá eu dou um split e chamo a proc normalmente! (porco mas funciona, vcs tem outra idéia?)

:?: Quando o login falha é lancado uma exceção no login module só que “alguma coisa” engole esta exceção e meu Handler exception nao pega ela! Tem como eu manipular as exceções lancadas no login module na jsp ( tipo eu queria na jsp algo como <%= exception.getMensage() %> )

Desde já obrigado pessoal!
Eu tenho q fazer isto até quarta… se eu não conseguir to ferrado! To mais preocupado com a segundo item, pois apesar da primeira solucao ser feia pelo menos é uma solucao! :roll:

Abri um tópico externo com o titulo 2 duvidas com JAAS!

velho … nao sei responder tua dúvida rsrs eu tenho várias ainda …

mas

tem como vc me dar uma breve explicação de como faz pra construir uma procedure no banco e delegar ela pra fazer a autenticação do JAAS?

valeu

F

É o mesmo processo que com o AD só muda que inves de chamar um método que vai validar no AD ele chama um metodo que chama um proc…

rodrigo_ctba:

Bom dia… em nossa arquitetura utilizamos o JAAS, inclusive com acesso ao banco e autenticação no AD.

Em resumo fizemos assim:

Criamos um LoginModule, e este realiza uma autenticação no AD, blz… as Roles são populadas apartir de uma query no banco de dados.

Para o seu caso, basta fazer a busca dos Principal no banco e suas respectivas Roles. Isso tudo deve ser codificado no LoginModule.

Alguns detalhes são:

No LoginModule faça um extends do DatabaseServerLoginModule.

Parte do initialize…

public void initialize(Subject subject, CallbackHandler callbackHandler,
			Map sharedState, Map options) {

		super.initialize(subject, callbackHandler, sharedState, options);
		this.subject = subject;
		this.callbackHandler = callbackHandler;
		this.sharedState = sharedState;

                // estou utilizando um ds.
		dsJndiName = (String) options.get("dsJndiName");

                // veja a query para o acesso o banco
		rolesQuery = "SELECT g.gruponome FROM lmod_usuario_grupo ug, lmod_usuario u, lmod_grupo g WHERE ug.usuario_usuarioid = u.usuarioid AND ug.grupo_grupoid = g.grupoid AND u.usuariochave=?";

	}

feito isso… fazemos uma autenticação no AD via LDAP… autenticando o usuário falta criar as autorizações… As Roles

Coisa básica, com Connection, PreparedStatement, etc…

protected Group[] getRoleSets() throws LoginException {

		Group[] groups = { new SimpleGroup("Roles") };
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			InitialContext ctx = new InitialContext();
			DataSource ds = (DataSource) ctx.lookup(dsJndiName);
			conn = ds.getConnection();

			ps = conn.prepareStatement(rolesQuery);
			ps.setString(1, getIdentity().getName());
			rs = ps.executeQuery();
			
			while (rs.next()) {
				String roleName = rs.getString(1);
				log.info(">>>>" + roleName);
				SimplePrincipal role = new SimplePrincipal(roleName);
				groups[0].addMember(role);				
			}
	
		} catch (Exception e) {
			e.printStackTrace();
		} finally {			
			try {
				rs.close();
				ps.close();
				conn.close();
			} catch (Exception e) {
				log.error("Error ao fechar as transações" + e.getMessage());
			}	
			
		}
		SimplePrincipal role = new SimplePrincipal("logado");
		groups[0].addMember(role);

		return groups;
	}

Bom … basicamente é isso… se tiver algum problema mais específico me avise !!!

Estou com este um problema, extra o JAAS
http://www.guj.com.br/posts/list/142275.java

Abraços !!!

t+

J

vixe …

nun sei fazer com AD

rsrs

vi que dá pra fazer no tomcat, configurando o AD como um JNDI e o resto fica como se fosse em um DB

mas do jeito q tu tah fazendo, seria implementando a interface LoginModule?

J

alguém me ajuda com a criptografia? please? :slight_smile:

só loga quando a senha nao esta criptografada e eu to usando o algoritmo correto …

e o sun-web.xml … alguem sabe pq nao funciona? ( explicação da pergunta … topico anterior)

valeu

G

javando, resolveu seu problema?

J

O Garcia, desculpa a demora.

Eu não consegui não :frowning:

parece que o tomcat não tá sabendo descriptografar a senha que tá no banco.

Mas tenho certeza que a senha que tá no banco está criptografada corretamente

talvez eu tenha uma pista …

eu fui realizar um teste no tomcat para ver se ele estava criptografando corretamente …

na documentação diz q é pra fazer o seguinte:

java org.apache.catalina.realm.RealmBase \

-a {algorithm} {cleartext-password}

eu coloquei o catalina.jar direitinho no path, mas quando eu chamo ele dá pela falta da seguinte classe:

org/apache/juli/logging/LogFactory

ai eu olhei no pacote catalina.jar e realmente o pacote juli está vazio :S

pedi pra um outro amigo meu ver o dele, e disse que tambem está vazio :S

será q eles está dando esse mesmo erro durante o login?

mas nao aparece nenhum erro no console… e nem nos logs do tomcat ( tomcat/logs/ )

alguem tem alguma ideia?

posso encontrar esse pacote q falta em algum lugar?

J

e então gente?

alguém? idéias?

parpites? rsrs

G

Você não pode alterar o local do catalina.jar. Ele tem que ficar lá no diretório padrão do tomcat e em nenhum outro local.

J

Você não pode alterar o local do catalina.jar. Ele tem que ficar lá no diretório padrão do tomcat e em nenhum outro local.

rsrs

eu não tirei do lugar … eu apenas botei o caminho dele na variavel de ambiente do path pra eu poder fazer uma chamada direta ao metodo que criptografa, realizar o teste assim como está descrito da documentação do tomcat:

http://tomcat.apache.org/tomcat-6.0-doc/realm-howto.html#Digested%20Passwords

To calculate the digested value of a cleartext password, two convenience techniques are supported:

* If you are writing an application that needs to calculate digested passwords dynamically, call the static Digest() method of the org.apache.catalina.realm.RealmBase class, passing the cleartext password and the digest algorithm name as arguments. This method will return the digested password.
* If you want to execute a command line utility to calculate the digested password, simply execute
  		
  	

  java org.apache.catalina.realm.RealmBase \
      -a {algorithm} {cleartext-password}

  	
  		
  and the digested version of this cleartext password will be returned to standard output.

If using digested passwords with DIGEST authentication, the cleartext used to generate the digest is different. In the examples above {cleartext-password} must be replaced with {username}:{realm}:{cleartext-password}. For example, in a development environment this might take the form testUser:localhost:8080:testPassword.

To use either of the above techniques, the $CATALINA_HOME/lib/catalina.jar and $CATALINA_HOME/bin/tomcat-juli.jar files will need to be on your class path to make the RealmBase class available.

só que a classe org.apache.catalina.realm.RealmBase que eu tenho q usar para esse teste dá por falta da classe org/apache/juli/logging/LogFactory que não existe no pacote catalina.jar :S

valeuu :slight_smile:

Criado 23 de outubro de 2009
Ultima resposta 5 de nov. de 2009
Respostas 47
Participantes 6