权限框架用的shiro,部署到contos7的tomcat77.0.54下,之前该tomcat下已经有几个项目,基本上用的是一个框架,都运行正常好好的,但新部署的项目就是登录不进,看日志,权限认证已经通过,但就是不跳转主页面,验证成功之后又跳回到了登录页面,而登录页面也不显示任何登录失败的消息,看控制台日志,一堆如下的东西:
Nov 27, 2017 9:54:44 PM org.apache.catalina.startup.ContextConfig processAnnotationsJar
SEVERE: Unable to process Jar entry [javassist/ClassClassPath.class] from Jar [jar:file:/usr/share/tomcat/webapps/OES2/WEB-INF/lib/javassist-3.20.0-GA.jar!/] for annotations
java.io.EOFException
at java.io.DataInputStream.readUnsignedShort(DataInputStream.java:340)
at org.apache.tomcat.util.bcel.classfile.Utility.swallowMethodParameters(Utility.java:797)
at org.apache.tomcat.util.bcel.classfile.Attribute.readAttribute(Attribute.java:171)
at org.apache.tomcat.util.bcel.classfile.FieldOrMethod.<init>(FieldOrMethod.java:57)
at org.apache.tomcat.util.bcel.classfile.Method.<init>(Method.java:71)
at org.apache.tomcat.util.bcel.classfile.ClassParser.readMethods(ClassParser.java:267)
at org.apache.tomcat.util.bcel.classfile.ClassParser.parse(ClassParser.java:127)
at org.apache.catalina.startup.ContextConfig.processAnnotationsStream(ContextConfig.java:2058)
at org.apache.catalina.startup.ContextConfig.processAnnotationsJar(ContextConfig.java:1934)
at org.apache.catalina.startup.ContextConfig.processAnnotationsUrl(ContextConfig.java:1900)
at org.apache.catalina.startup.ContextConfig.processAnnotations(ContextConfig.java:1885)
at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1317)
at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:876)
at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:374)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5355)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.startup.HostConfig.reload(HostConfig.java:1487)
at org.apache.catalina.startup.HostConfig.checkResources(HostConfig.java:1465)
at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1649)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:328)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1374)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1530)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1519)
at java.lang.Thread.run(Thread.java:745)
以及如下的信息:
Nov 27, 2017 9:54:44 PM org.apache.catalina.startup.ContextConfig processAnnotationsJar
SEVERE: Unable to process Jar entry [javassist/ClassPool.class] from Jar [jar:file:/usr/share/tomcat/webappsZhengZhou/OES2/WEB-INF/lib/javassist-3.20.0-GA.jar!/] for annotations
org.apache.tomcat.util.bcel.classfile.ClassFormatException: Invalid constant pool reference: 2817. Constant pool size is: 528
at org.apache.tomcat.util.bcel.classfile.ConstantPool.getConstant(ConstantPool.java:183)
at org.apache.tomcat.util.bcel.classfile.ConstantPool.getConstant(ConstantPool.java:202)
at org.apache.tomcat.util.bcel.classfile.Attribute.readAttribute(Attribute.java:94)
at org.apache.tomcat.util.bcel.classfile.FieldOrMethod.<init>(FieldOrMethod.java:57)
at org.apache.tomcat.util.bcel.classfile.Method.<init>(Method.java:71)
at org.apache.tomcat.util.bcel.classfile.ClassParser.readMethods(ClassParser.java:267)
at org.apache.tomcat.util.bcel.classfile.ClassParser.parse(ClassParser.java:127)
at org.apache.catalina.startup.ContextConfig.processAnnotationsStream(ContextConfig.java:2058)
at org.apache.catalina.startup.ContextConfig.processAnnotationsJar(ContextConfig.java:1934)
at org.apache.catalina.startup.ContextConfig.processAnnotationsUrl(ContextConfig.java:1900)
at org.apache.catalina.startup.ContextConfig.processAnnotations(ContextConfig.java:1885)
at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1317)
at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:876)
at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:374)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5355)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.startup.HostConfig.reload(HostConfig.java:1487)
at org.apache.catalina.startup.HostConfig.checkResources(HostConfig.java:1465)
at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1649)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:328)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1374)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1530)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1519)
at java.lang.Thread.run(Thread.java:745)
之前服务器上部署过一个项目似乎也出现过这种情况,也是控制台出这种错误,后来忘记是怎么操作又好了的,可以登录了,可是会出现一会儿能登录一会儿不能登录,重启一控下就可以了,制台日志里仍有这种错误,想了各种方法都无法解决,也忘记都做什么操作了,重下载包啊,清缓存啊,清工作目录啊,解决冲突啊,凡此种种,后来忽然间就好了,具体原因不清楚,因为太忙,也就不了了之了。
这次又碰到这种问题,初始一见这个错误就觉得跟它没多大关系,就没往这边考虑,可问题是除此之外系统没任何错误,连登录页面的登录失败提示也没有。后来百度来百度去,有人提到JDK版本相关的问题,于是考虑到服务器上JDK为1.7,本机是1.8+1.7,是不是编译的问题?于是将所有文件重新用1.7编译一遍,再放服务器还是不行,但是不知道是好是坏的,原来本机在eclipse下运行一下没有任何问题,所以无法调试,经过一翻折腾,本机终于也出现同样的问题了。
于是根据服务器日志上输出的最后一条信息,找到相对应的语句,是自定义的shiro的realm文件,里面最后一句:
SimpleAuthenticationInfo saci = new SimpleAuthenticationInfo(user, user.getPassword(), getName());
logger.info("【" + user.getName() + "(" + user.getLoginname() + ")" + "】登录系统");
return saci;
前面其实已经验证通过了,就是在return saci的时候出现了问题,但并没有抛出异常。
于是断点设置到这里,一步一步跟踪进入shiro源码,终于发现是下面的异常:
org.apache.shiro.authc.AuthenticationException: A CredentialsMatcher must be configured in order to verify credentials during authentication. If you do not wish for credentials to be examined, you can configure an org.apache.shiro.authc.credential.AllowAllCredentialsMatcher instance.
at org.apache.shiro.realm.AuthenticatingRealm.assertCredentialsMatch(AuthenticatingRealm.java:608)
at org.apache.shiro.realm.AuthenticatingRealm.getAuthenticationInfo(AuthenticatingRealm.java:581)
at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doSingleRealmAuthentication(ModularRealmAuthenticator.java:180)
at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doAuthenticate(ModularRealmAuthenticator.java:267)
at org.apache.shiro.authc.AbstractAuthenticator.authenticate(AbstractAuthenticator.java:198)
at org.apache.shiro.mgt.AuthenticatingSecurityManager.authenticate(AuthenticatingSecurityManager.java:106)
at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:274)
at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:260)
at org.apache.shiro.web.filter.authc.AuthenticatingFilter.executeLogin(AuthenticatingFilter.java:53)
at org.apache.shiro.web.filter.authc.FormAuthenticationFilter.onAccessDenied(FormAuthenticationFilter.java:154)
at org.apache.shiro.web.filter.AccessControlFilter.onAccessDenied(AccessControlFilter.java:133)
at org.apache.shiro.web.filter.AccessControlFilter.onPreHandle(AccessControlFilter.java:162)
at org.apache.shiro.web.filter.PathMatchingFilter.isFilterChainContinued(PathMatchingFilter.java:203)
at org.apache.shiro.web.filter.PathMatchingFilter.preHandle(PathMatchingFilter.java:178)
at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:131)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:387)
at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:178)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
字面上理解,就是说我没有配置CredentialsMatcher,可是我的配置文件里明明配置有
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
default-lazy-init="true">
<description>Shiro Configuration</description>
<!-- Shiro Filter -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/login.action" />
<property name="successUrl" value="/main.action" />
<property name="unauthorizedUrl" value="/login?unauthorized=true" />
<property name="filterChainDefinitions">
<value>
/login.action = authc
/logout.action = logout
/static/** = anon
/login!getVerifyCode.action = anon
/login!reGetVerifyCode.action = anon
/login!checkVerifyCode.action = anon
/login!getImageCode.action = anon
/login!checkImageCode.action = anon
/httpservice/**=anon
/app/**=anon
/web/**=anon
/errorpage/**=anon
/** = authc
</value>
</property>
</bean>
<!-- Shiro's main business-tier object for web-enabled applications -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="shiroDbRealm" />
<property name="cacheManager" ref="cacheManager" />
<property name="sessionManager" ref="sessionManager" />
</bean>
<!-- 項目自定义Realm -->
<bean id="shiroDbRealm" class="top.mgsoft.mvc.system.service.ShiroDbRealm">
<property name="credentialsMatcher" ref="credentialsMatcher"/>
</bean>
<bean id="credentialsMatcher" class="mypackage.CustomCredentialsMatcher">
<constructor-arg ref="cacheManager"/>
<property name="passwordRetryTimes" value="5"/>
</bean>
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml" />
</bean>
<!-- <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" /> -->
<bean id="sessionManager"
class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="sessionIdUrlRewritingEnabled" value="false" />
<property name="sessionValidationInterval" value="1800000" />
<property name="globalSessionTimeout" value="1800000" />
<property name="sessionDAO" ref="sessionDAO" />
</bean>
<bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO" />
<bean
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true" />
</bean>
<bean
class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager" />
</bean>
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
</beans>
这不科学啊。
考虑到自己eclipse下原本正常,而所有动作不过就是重新编译,于是把自己定义的包,项目包重新拿1.8进行编译,然后,本机居然好了。然后又重新恢复到1.7,居然也是好的。说到这儿我不得不怀疑eclipse是有bug的,我怀疑它在做某些编译的时候,并没有全部编译文件,即使我们项目执行了clean,maven clean,甚至将jdk版本换掉,总之,项目原来正常时我使用的编译环境,后来登录不进的时候的编译环境,以及后来又正常后的编译环境,其实都是一种环境,就是jdk7。当然,之所以会有不正常,我也怀疑跟我本机上装了两个版本的jdk,而系统指向的JAVA_HOME是1.8有一定的关系。
可本机好了,服务器上仍是不行,具体原因仍不详。
新来的小同事帮忙测试,干脆在服务器上又装上了tomcat8(原来是tomcat7),也是不行,再干脆,在服务器上装上了jdk8(原来是openjdk1.7),tomcat8指向jdk8,然后就可以了!!!
考虑到以后项目用jdk8居多,再说又是向下兼容,干脆让小同事将原来的tomcat也指向到1.8,然后,一切都解决了。
最终的解决方案是,换了服务器上的jdk。
最终得出的结论是:编译环境的问题。
供大家参考。