简体   繁体   English

JDBC Realm身份验证错误Glassfish 4

[英]JDBC Realm authentication bug Glassfish 4

Ok so I have spent a good amount of time on this but, it would appear that everything is set correctly and there is a bug in the com.sun.enterprise.security.ee.auth.realm.jdbc.JDBCRealm code. 好的,所以我花了很多时间在此上,但是似乎所有设置都正确,并且com.sun.enterprise.security.ee.auth.realm.jdbc.JDBCRealm代码中存在错误。

I am attempting to use form based authentication with programmatic log in. I am using Glassfish 4 and JDK 1.8_40. 我正在尝试通过编程式登录使用基于表单的身份验证。我正在使用Glassfish 4和JDK 1.8_40。 When I enter my details into the login page the container attempts to direct me to the secured resource however it gives me a access denied at the same URL. 当我在登录页面中输入我的详细信息时,容器会尝试将我定向到受保护的资源,但是,它使我无法使用同一URL进行访问。 Upon investigating this I have discovered that although the login succeeded the container failed to validate my login and has failed to associate the principle with any roles. 经过调查,我发现尽管登录成功,但容器仍无法验证我的登录名,并且未能将该原理与任何角色相关联。 This causing the access denied error. 这导致访问被拒绝错误。 In order to discover what was going on I set the logging on glass fish to fine and discovered the array index out of bounds error seen in the stack trace. 为了发现正在发生的事情,我将玻璃鱼的记录设置为精细,并发现了堆栈跟踪中看到的数组索引超出范围错误。

[2015-03-25T16:19:43.088+0100] [glassfish 4.0] [FINE] [] [javax.enterprise.system.core.security.com.sun.enterprise.security.auth.realm] [tid: _ThreadID=59 _ThreadName=http-listener-1(4)] [timeMillis: 1427296783088] [levelValue: 500] [CLASSNAME: com.sun.enterprise.security.ee.auth.realm.jdbc.JDBCRealm] [METHODNAME: isUserValid] [[
  Cannot validate user
java.lang.ArrayIndexOutOfBoundsException: 64
    at com.sun.enterprise.security.ee.auth.realm.jdbc.JDBCRealm.isUserValid(JDBCRealm.java:430)
    at com.sun.enterprise.security.ee.auth.realm.jdbc.JDBCRealm.authenticate(JDBCRealm.java:324)
    at com.sun.enterprise.security.ee.auth.login.JDBCLoginModule.authenticate(JDBCLoginModule.java:78)
    at com.sun.enterprise.security.auth.login.PasswordLoginModule.authenticateUser(PasswordLoginModule.java:116)
    at com.sun.enterprise.security.BasePasswordLoginModule.login(BasePasswordLoginModule.java:146)
    at sun.reflect.GeneratedMethodAccessor78.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)
    at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195)
    at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682)
    at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
    at javax.security.auth.login.LoginContext.login(LoginContext.java:587)
    at com.sun.enterprise.security.auth.login.LoginContextDriver.doPasswordLogin(LoginContextDriver.java:383)
    at com.sun.enterprise.security.auth.login.LoginContextDriver.login(LoginContextDriver.java:241)
    at com.sun.enterprise.security.auth.login.LoginContextDriver.login(LoginContextDriver.java:154)
    at com.sun.web.security.RealmAdapter.authenticate(RealmAdapter.java:695)
    at com.sun.web.security.RealmAdapter.authenticate(RealmAdapter.java:636)
    at org.apache.catalina.authenticator.AuthenticatorBase.doLogin(AuthenticatorBase.java:957)
    at org.apache.catalina.authenticator.AuthenticatorBase.login(AuthenticatorBase.java:939)
    at org.apache.catalina.connector.Request.login(Request.java:2245)
    at org.apache.catalina.connector.Request.login(Request.java:2224)
    at org.apache.catalina.connector.RequestFacade.login(RequestFacade.java:1113)
    at com.merrimansa.beans.UserAuthBean.login(UserAuthBean.java:80)
    at com.merrimansa.beans.UserAuthBean$Proxy$_$$_WeldClientProxy.login(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at javax.el.ELUtil.invokeMethod(ELUtil.java:326)
    at javax.el.BeanELResolver.invoke(BeanELResolver.java:536)
    at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:256)
    at com.sun.el.parser.AstValue.invoke(AstValue.java:269)
    at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
    at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
    at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:147)
    at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
    at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:818)
    at javax.faces.component.UICommand.broadcast(UICommand.java:300)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
    at java.lang.Thread.run(Thread.java:745)
]]

[2015-03-25T16:19:43.150+0100] [glassfish 4.0] [FINE] [] [javax.enterprise.system.core.security] [tid: _ThreadID=33 _ThreadName=admin-listener(2)] [timeMillis: 1427296783150] [levelValue: 500] [CLASSNAME: com.sun.enterprise.security.web.integration.WebSecurityManager] [METHODNAME: setPolicyContext] [[
  [Web-Security] Policy Context ID was: __admingui/__admingui]]

[2015-03-25T16:19:43.151+0100] [glassfish 4.0] [FINE] [] [javax.enterprise.system.core.security] [tid: _ThreadID=33 _ThreadName=admin-listener(2)] [timeMillis: 1427296783151] [levelValue: 500] [CLASSNAME: com.sun.enterprise.security.web.integration.WebSecurityManager] [METHODNAME: checkPermissionWithoutCache] [[
  [Web-Security] Codesource with Web URL: file:/__admingui/__admingui]]

[2015-03-25T16:19:43.151+0100] [glassfish 4.0] [FINE] [] [javax.enterprise.system.core.security] [tid: _ThreadID=33 _ThreadName=admin-listener(2)] [timeMillis: 1427296783151] [levelValue: 500] [CLASSNAME: com.sun.enterprise.security.web.integration.WebSecurityManager] [METHODNAME: checkPermissionWithoutCache] [[
  [Web-Security] Checking Web Permission with Principals : null]]

[2015-03-25T16:19:43.151+0100] [glassfish 4.0] [FINE] [] [javax.enterprise.system.core.security] [tid: _ThreadID=33 _ThreadName=admin-listener(2)] [timeMillis: 1427296783151] [levelValue: 500] [CLASSNAME: com.sun.enterprise.security.web.integration.WebSecurityManager] [METHODNAME: checkPermissionWithoutCache] [[
  [Web-Security] Web Permission = ("javax.security.jacc.WebResourcePermission" "/download/log/" "GET")]]

[2015-03-25T16:19:43.151+0100] [glassfish 4.0] [FINE] [] [javax.enterprise.system.core.security.com.sun.enterprise.security.jmac.config] [tid: _ThreadID=33 _ThreadName=admin-listener(2)] [timeMillis: 1427296783151] [levelValue: 500] [CLASSNAME: com.sun.enterprise.security.jmac.config.GFServerConfigProvider] [METHODNAME: getEntry] [[
  getEntry for: HttpServlet -- GFConsoleAuthModule
    module class: org.glassfish.admingui.common.security.AdminConsoleAuthModule
    options: {loginErrorPage=/loginError.jsf, loginPage=/login.jsf}
    request policy: javax.security.auth.message.MessagePolicy@7a09d92
    response policy: null]]

[2015-03-25T16:19:43.182+0100] [glassfish 4.0] [FINE] [] [javax.enterprise.system.core.security.com.sun.enterprise.security.auth.realm] [tid: _ThreadID=252 _ThreadName=admin-listener(9)] [timeMillis: 1427296783182] [levelValue: 500] [CLASSNAME: com.sun.enterprise.security.auth.realm.file.FileRealm] [METHODNAME: init] [[
  FileRealm : file=/etc/Glassfish4/glassfish4/glassfish/domains/domain1/config/admin-keyfile]]

[2015-03-25T16:19:43.182+0100] [glassfish 4.0] [FINE] [] [javax.enterprise.system.core.security.com.sun.enterprise.security.auth.realm] [tid: _ThreadID=252 _ThreadName=admin-listener(9)] [timeMillis: 1427296783182] [levelValue: 500] [CLASSNAME: com.sun.enterprise.security.auth.realm.file.FileRealm] [METHODNAME: init] [[
  FileRealm : jaas-context=ignore]]

[2015-03-25T16:19:43.184+0100] [glassfish 4.0] [FINE] [] [javax.enterprise.system.core.security.com.sun.enterprise.security] [tid: _ThreadID=252 _ThreadName=admin-listener(9)] [timeMillis: 1427296783184] [levelValue: 500] [CLASSNAME: com.sun.enterprise.security.BasePasswordLoginModule] [METHODNAME: initialize] [[
  Login module initialized: class com.sun.enterprise.security.auth.login.FileLoginModule]]

[2015-03-25T16:19:43.184+0100] [glassfish 4.0] [FINE] [] [javax.enterprise.system.core.security.com.sun.enterprise.security] [tid: _ThreadID=252 _ThreadName=admin-listener(9)] [timeMillis: 1427296783184] [levelValue: 500] [CLASSNAME: com.sun.enterprise.security.BasePasswordLoginModule] [METHODNAME: abort] [[
  JAAS authentication aborted.]]

[2015-03-25T16:19:43.197+0100] [glassfish 4.0] [FINE] [] [javax.enterprise.system.core.security.com.sun.enterprise.security] [tid: _ThreadID=59 _ThreadName=http-listener-1(4)] [timeMillis: 1427296783197] [levelValue: 500] [CLASSNAME: com.sun.enterprise.security.BasePasswordLoginModule] [METHODNAME: login] [[
  JAAS login complete.]]

[2015-03-25T16:19:43.197+0100] [glassfish 4.0] [FINE] [] [javax.enterprise.system.core.security.com.sun.enterprise.security] [tid: _ThreadID=59 _ThreadName=http-listener-1(4)] [timeMillis: 1427296783197] [levelValue: 500] [CLASSNAME: com.sun.enterprise.security.BasePasswordLoginModule] [METHODNAME: commit] [[
  JAAS authentication committed.]]

[2015-03-25T16:19:43.198+0100] [glassfish 4.0] [FINE] [] [javax.enterprise.system.core.security.com.sun.enterprise.security.auth.login] [tid: _ThreadID=59 _ThreadName=http-listener-1(4)] [timeMillis: 1427296783198] [levelValue: 500] [CLASSNAME: com.sun.enterprise.security.auth.login.LoginContextDriver] [METHODNAME: doPasswordLogin] [[
  Password login succeeded for : Steve.Merriman@fluid.contitech.co.uk]]

[2015-03-25T16:19:43.207+0100] [glassfish 4.0] [FINE] [] [javax.enterprise.system.core.security.com.sun.enterprise.security.auth.login] [tid: _ThreadID=59 _ThreadName=http-listener-1(4)] [timeMillis: 1427296783207] [levelValue: 500] [CLASSNAME: com.sun.enterprise.security.auth.login.LoginContextDriver] [METHODNAME: doPasswordLogin] [[
  Set security context as user: Steve.Merriman@fluid.contitech.co.uk]]

[2015-03-25T16:19:43.467+0100] [glassfish 4.0] [FINE] [] [javax.enterprise.system.core.security] [tid: _ThreadID=56 _ThreadName=http-listener-1(1)] [timeMillis: 1427296783467] [levelValue: 500] [CLASSNAME: com.sun.enterprise.security.web.integration.WebSecurityManager] [METHODNAME: setPolicyContext] [[
  [Web-Security] Setting Policy Context ID: old = null ctxID = HSEManagmentApp/HSEManagmentApp]]

I then investigated the source code for the method in question and discovered a comment saying it could accept a maximum length of 50 see code below. 然后,我研究了该方法的源代码,并发现一条注释,说它可以接受最大长度为50的代码,请参见下面的代码。 I'm not sure if this is a red herring or if I have just set something wrong in my JDBC realm. 我不确定这是一个红鲱鱼还是在JDBC领域中设置了错误。 Any help on this would be much appreciated as it is eating up my time and I'm no closer to a solution. 对此的任何帮助将不胜感激,因为它占用了我的时间,而且我离解决方案还很近。

private boolean isUserValid(String user, char[] password) {
401        Connection connection = null;
402        PreparedStatement statement = null;
403        ResultSet rs = null;
404        boolean valid = false;
405
406        try {
407            char[] hpwd = hashPassword(password);
408            connection = getConnection();
409            statement =  connection.prepareStatement(passwordQuery);
410            statement.setString(1, user);
411            rs = statement.executeQuery();
412            if (rs.next()) {
413                //Obtain the password as a char[] with a  max size of 50
414                Reader reader =  rs.getCharacterStream(1);
415                char[] pwd = new char[1024];
416                int noOfChars = reader.read(pwd);
417
418                /*Since pwd contains 1024 elements arbitrarily initialized,
419                    construct a new char[] that has the right no of char elements
420                    to be used for equal comparison*/
421                if (noOfChars < 0) {
422                    noOfChars = 0;
423                }
424                char[] passwd = new char[noOfChars];
425                System.arraycopy(pwd, 0, passwd, 0, noOfChars);
426                if (HEX.equalsIgnoreCase(getProperty(PARAM_ENCODING))) {
427                    valid = true;
428                    //Do a case-insensitive equals
429                    for(int i = 0; i < noOfChars; i ++) {
430                        if (!(Character.toLowerCase(passwd[i]) == Character.toLowerCase(hpwd[i]))) {
431                            valid = false;
432                            break;
433                        }
434                    }
435                } else {
436                    valid = Arrays.equals(passwd, hpwd);
437                }
438            }
439        } catch(SQLException ex) {
440                _logger.log(Level.SEVERE, "jdbcrealm.invaliduserreason", 
441                        new String [] {user,ex.toString()});
442            if (_logger.isLoggable(Level.FINE)) {
443                _logger.log(Level.FINE, "Cannot validate user", ex);
444            } 
445        } catch(Exception ex) {
446            _logger.log(Level.SEVERE, "jdbcrealm.invaliduser", user);
447            if (_logger.isLoggable(Level.FINE)) {
448                _logger.log(Level.FINE, "Cannot validate user", ex);
449            }
450        } finally {
451            close(connection, statement, rs);
452        }
453        return valid;
454    }

I have attached my realm file in case it is something silly but I have tried just about every combination. 我附上了我的领域文件,以防万一这很愚蠢,但是我几乎尝试了每种组合。 I have also checked my hashing in the database and it is correct. 我还检查了数据库中的哈希,它是正确的。 Only odd thing is if I set hashing to 'none' then it doesn't work at all. 唯一奇怪的是,如果我将哈希设置为“无”,则它根本不起作用。

Ok I have solved this issue and all the others I was having with authentication and wanted to post an answer for future people facing this problem. 好的,我已经解决了这个问题,并且我通过身份验证解决了所有其他问题,并希望为将来遇到此问题的人们提供答案。 It seems that the SQL queries being used are filling in any unused space in the database field with white space so; 似乎正在使用的SQL查询正在用空格填充数据库字段中任何未使用的空间; as I had my password field set to nvarchar(500) that was the length of the password that was being returned although all characters after 64 were white space. 因为我将密码字段设置为nvarchar(500),这是返回的密码长度,尽管64位之后的所有字符都是空格。 This also caused an issue with role to group mapping, as this is a various length field I cant change the field length to compensate so must now look for the problem with the driver or queries involved. 这也引起了组映射角色的问题,因为这是一个可变长度的字段,我无法更改字段长度以进行补偿,因此现在必须查找驱动程序或所涉及查询的问题。

Regards 问候

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM