错误:函数crypt(字符变化,字符变化)不存在

时间:2018-03-16 12:13:40

标签: java postgresql jdbc

对于一个小项目,我正在使用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中相同的数据库,用户和模式。

1 个答案:

答案 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();    
}