java.lang.ClassCastException: [B> не может быть приведен к java.lang.String - PullRequest
8 голосов
/ 11 января 2011
public Login authenticate(Login login) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            String password = login.getPassword();
            try {
                md.update(password.getBytes("UTF-16"));
                byte[] digest = md.digest();
                String query = "SELECT L FROM Login AS L WHERE L.email=? AND L.password=?";
                Object[] parameters = { login.getEmail(), digest };
                List<Login> resultsList = (getHibernateTemplate().find(query,parameters));
                 if (resultsList.isEmpty()) {
                         //error dude
                     }
                 else if (resultsList.size() > 1) {
                         //throw expections
                     }
                 else {
                       Login login1 = (Login) resultsList.get(0);
                       return login1;
                 }
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }                
       return null;  
    }

Исключение

> java.lang.ClassCastException: [B
> cannot be cast to java.lang.String
>         at org.hibernate.type.StringType.toString(StringType.java:44)
>         at org.hibernate.type.NullableType.nullSafeToString(NullableType.java:93)
>         at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:140)
>         at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:116)
>         at org.hibernate.param.PositionalParameterSpecification.bind(PositionalParameterSpecification.java:39)
>         at org.hibernate.loader.hql.QueryLoader.bindParameterValues(QueryLoader.java:491)
>         at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1563)
>         at org.hibernate.loader.Loader.doQuery(Loader.java:673)
>         at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
>         at org.hibernate.loader.Loader.doList(Loader.java:2213)
>         at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)
>         at org.hibernate.loader.Loader.list(Loader.java:2099)
>         at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:378)
>         at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338)
>         at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
>         at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121)
>         at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
>         at org.springframework.orm.hibernate3.HibernateTemplate$29.doInHibernate(HibernateTemplate.java:856)
>         at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:373)
>         at org.springframework.orm.hibernate3.HibernateTemplate.find(HibernateTemplate.java:847)
>         at com.intermedix.services.LoginService.authenticate(LoginService.java:30)
>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
> Method)
>         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>         at java.lang.reflect.Method.invoke(Method.java:597)
>         at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:301)
>         at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
>         at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
>         at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
>         at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
>         at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
>         at $Proxy31.authenticate(Unknown Source)
>         at com.intermedix.ui.LoginDailog.checkLogin(LoginDailog.java:106)
>         at com.intermedix.ui.LoginDailog.access$0(LoginDailog.java:102)
>         at com.intermedix.ui.LoginDailog$2.handleAction(LoginDailog.java:88)
>         at com.vaadin.event.ActionManager.handleAction(ActionManager.java:228)
>         at com.vaadin.event.ActionManager.handleActions(ActionManager.java:198)
>         at com.vaadin.ui.Panel.changeVariables(Panel.java:345)
>         at com.vaadin.ui.Window.changeVariables(Window.java:1073)
>         at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.handleVariables(AbstractCommunicationManager.java:1094)
>         at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.doHandleUidlRequest(AbstractCommunicationManager.java:590)
>         at com.vaadin.terminal.gwt.server.CommunicationManager.handleUidlRequest(CommunicationManager.java:266)
>         at com.vaadin.terminal.gwt.server.AbstractApplicationServlet.service(AbstractApplicationServlet.java:476)
>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>         at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
>         at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:390)
>         at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
>         at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
>         at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>         at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
>         at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
>         at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
>         at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>         at org.mortbay.jetty.Server.handle(Server.java:326)
>         at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
>         at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:943)
>         at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
>         at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
>         at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
>         at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410)
>         at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

Ответы [ 3 ]

6 голосов
/ 11 января 2011

Кажется, что столбец пароля вашей базы данных - это тип, обозначенный как String в Java (varchar, наиболее вероятно). Таким образом, Hibernate не может преобразовать ваш байт array в String.

Вы можете изменить свои строки на что-то вроде:

 String digest = new String(md.digest());
 String query = "SELECT L FROM Login AS L WHERE L.email=? AND L.password=?";
 Object[] parameters = { login.getEmail(), digest };

Но, вероятно, это не сработает, поскольку дайджест, скорее всего, будет содержать байты, не отображаемые в символы независимо от кодировки. Вероятно, вам следует использовать кодировку base64 , чтобы отобразить двоичный двоичный объект в строку.

Другое решение будет состоять в том, чтобы изменить схему базы данных и сделать поле password двоичным, а не varchar.

В обоих случаях вам нужно знать, как поле password вставляется в базу данных.

Некоторые замечания по вашему коду:

Мне кажется странным, что вы проверяете пароль, выбирая строку из вашей базы данных с именем пользователя и паролем. Хотя было бы логичнее выбрать, используя только пользователя, а затем проверить предоставленный пароль по сравнению с паролем, возвращенным в базе данных.

Вы используете хеш-функцию, чтобы гарантировать, что ваш пароль не будет сохранен в виде обычного текста в базе данных. Это хорошо. Однако ваша схема имеет большой недостаток: если несколько пользователей имеют один и тот же пароль, то хешированный пароль будет одинаковым в базе данных. Так что, если у вас есть доступ к базе данных и вы знаете пароль одного пользователя, вам будет очень легко найти всех пользователей, разделяющих этот пароль. Чтобы создать что-то более безопасное, вы должны использовать схему кодирования пароля, которая включает в себя salt .

2 голосов
/ 11 января 2011

похоже, что вы [передаете байтовый массив, где требуется строка.

попробуйте { login.getEmail(), new String(digest) }; вместо { login.getEmail(), digest };

см. http://download.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#String%28byte[]%29

0 голосов
/ 11 января 2011

Ошибка, кажется, в строке 30, которую я предполагаю, это строка параметров Object[]. В этом случае вам нужно преобразовать byte[] дайджест в строку и использовать строку в качестве параметра.

этот ответ был дан до того, как вопрос был отредактирован.

Оберните вещи в функции:

byte[] digest = getMessageDigest(login.getPassword());
login1 = verifyPassword(login.getEmail(), digest);

конечно, соответствующие try / catch все еще там.

Попробуйте отойти от привычки e.printStackTrace() к записи в файлы журналов с помощью java.utils.logging.Logger или log4j.

попытаться получить только один возврат в функцию. если вы сохраняете код таким же, определите Login login1=null в начале функции и просто назначьте в блоке else. Возвращаемое значение в конце должно быть return login1 (что будет нулевым или некоторым значением).

части, где у вас есть код, который еще предстоит реализовать (например, ошибка чувак), должны быть прокомментированы с //TODO:. Большинство идентификаторов, таких как eclipse / netbeans, автоматически находят эти комментарии как задачи.

...