对于一个小项目,我正在使用JSP和JDBC建立一个虚拟网站(目前只在我的笔记本上运行本地)。它主要是为了接触上述技术以及HTML和CSS。
我现在正希望用户能够登录该网站。我之前使用未在数据库中加密的密码成功测试了它。出于明显的安全原因,我想使用' pgcrypto'来加密数据库中的密码。 PostgreSQL的扩展。
我通过pgAdmin设置了所有内容并在那里成功测试了所有SQL。插入的用户仅用于测试目的,我以后不会使用此用户。
CREATE EXTENSION pgcrypto
CREATE TABLE s68.USERS(
userid SERIAL NOT NULL PRIMARY KEY,
username VARCHAR (150) NOT NULL ,
password VARCHAR NOT NULL,
usergrp VARCHAR (20) NOT NULL,
CONSTRAINT chk_usergrp CHECK(usergrp IN('admin','trainer','news'))
);
INSERT INTO s68.users(username,password,usergrp)
VALUES ('admin',crypt('admin', gen_salt('bf')),'admin');
不幸的是,当我尝试通过JDBC运行SQL以便我可以登录时,我得到以下SQLException:
org.postgresql.util.PSQLException: ERROR: function crypt(character varying, character varying) does not exist Hinweis: No function matches the given name and argument types. You might need to add explicit type casts. Position: 63 at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2422) at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2167) at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:306) at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:441) at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:365) at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:155) at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:118) at beans.LoginBean.checkUseridPasswordSicher(LoginBean.java:50) at beans.LoginBean.checkUseridPassword(LoginBean.java:26) at org.apache.jsp.jsp.LoginAppl_jsp._jspService(LoginAppl_jsp.java:170) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:444) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330) at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:494) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:407) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:754) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1376) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Unknown Source)
这是我的函数代码,用于检查用户名和密码是否正确:
public boolean checkUseridPassword() throws NoConnectionException, SQLException{
String sql = "SELECT username from users "
+ "where username = ? and password = crypt(?, password)";
System.out.println(sql);
Connection dbConn = new PostgreSQLAccess().getConnection();
PreparedStatement prep = dbConn.prepareStatement(sql);
prep.setString(1, this.getUsername());
prep.setString(2, this.getPassword());
ResultSet dbRes = prep.executeQuery();
return dbRes.next();
}
我在pgAdmin中使用与JDBC中相同的数据库,用户和模式。
答案 0 :(得分:0)
尽管最初的问题是在两年前,但我也遇到过同样的问题。
我的解决方案是在pgcrypto函数上创建一个显式的“公共”模式。
使用pgAdmin,我没有连接任何显式模式,并且一切正常,但是使用JDBC,我连接了一个不同的默认模式,并且coludn看不到加密功能。
在我的情况下,我设置了公共模式和强制转换参数(前字符转换为文本),从而解决了问题:public.crypt(text(*text_to_encrypt*),text(*salt_text*) )
当JDBC连接设置为默认模式“ s86”时,这对我有用:
public boolean checkUseridPassword() throws NoConnectionException, SQLException{
String sql = "SELECT username from users "
+ "where username = ? and password = public.crypt(text(?), text(password) )";
System.out.println(sql);
Connection dbConn = new PostgreSQLAccess().getConnection();
PreparedStatement prep = dbConn.prepareStatement(sql);
prep.setString(1, this.getUsername());
prep.setString(2, this.getPassword());
ResultSet dbRes = prep.executeQuery();
return dbRes.next();
}