atjiu / pybbs

更实用的Java开发的社区(论坛),Better use of Java development community (forum)
GNU Affero General Public License v3.0
1.84k stars 706 forks source link

记住我,后台报错,功能失效。 #84

Closed Liuguozhu closed 4 years ago

Liuguozhu commented 5 years ago
10:21:49.169 OPHYER [XNIO-1 task-5] INFO  c.y.pybbs.config.realm.MyShiroRealm - 用户:admin 正在登录...
10:21:49.328 OPHYER [XNIO-1 task-5] WARN  o.a.shiro.mgt.DefaultSecurityManager - Delegate RememberMeManager instance of type [org.apache.shiro.web.mgt.CookieRememberMeManager] threw an exception during onSuccessfulLogin.  RememberMe services will not be performed for account [admin].
org.apache.shiro.crypto.CryptoException: Unable to init cipher instance.
    at org.apache.shiro.crypto.JcaCipherService.init(JcaCipherService.java:495)
    at org.apache.shiro.crypto.JcaCipherService.initNewCipher(JcaCipherService.java:598)
    at org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:444)
    at org.apache.shiro.crypto.JcaCipherService.encrypt(JcaCipherService.java:324)
    at org.apache.shiro.crypto.JcaCipherService.encrypt(JcaCipherService.java:313)
    at org.apache.shiro.mgt.AbstractRememberMeManager.encrypt(AbstractRememberMeManager.java:466)
    at org.apache.shiro.mgt.AbstractRememberMeManager.convertPrincipalsToBytes(AbstractRememberMeManager.java:352)
    at org.apache.shiro.mgt.AbstractRememberMeManager.rememberIdentity(AbstractRememberMeManager.java:336)
    at org.apache.shiro.mgt.AbstractRememberMeManager.rememberIdentity(AbstractRememberMeManager.java:311)
    at org.apache.shiro.mgt.AbstractRememberMeManager.onSuccessfulLogin(AbstractRememberMeManager.java:287)
    at org.apache.shiro.mgt.DefaultSecurityManager.rememberMeSuccessfulLogin(DefaultSecurityManager.java:210)
    at org.apache.shiro.mgt.DefaultSecurityManager.onSuccessfulLogin(DefaultSecurityManager.java:295)
    at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:289)
    at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:260)
    at co.yiiu.pybbs.controller.front.IndexController.adminlogin(IndexController.java:139)
    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:483)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:665)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)
    at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
    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 io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
    at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132)
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
    at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.SessionRestoringHandler.handleRequest(SessionRestoringHandler.java:119)
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
    at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
    at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
    at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
    at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
    at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:360)
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.security.InvalidKeyException: Illegal key size
    at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1034)
    at javax.crypto.Cipher.implInit(Cipher.java:800)
    at javax.crypto.Cipher.chooseProvider(Cipher.java:859)
    at javax.crypto.Cipher.init(Cipher.java:1370)
    at javax.crypto.Cipher.init(Cipher.java:1301)
    at org.apache.shiro.crypto.JcaCipherService.init(JcaCipherService.java:488)
    ... 75 common frames omitted`

暂时未找到解决方案

atjiu commented 5 years ago

你改代码了吗? 这好像是写cookie时加密出的问题

Liuguozhu commented 5 years ago

这部分代码没改

atjiu commented 5 years ago

@Liuguozhu 你jdk版本是多少?

Liuguozhu commented 5 years ago

1.8.0_31

atjiu commented 5 years ago

@Liuguozhu 如果不对pybbs源码做任务修改, 直接启动有这个错吗?

我在网上找了一下, 没有找到啥好办法, 都说是加密问题, 如果ShiroConfig 类你没有修改东西, 应该不会出现这个错的

Liuguozhu commented 5 years ago

这个没改过啊,我就了点别的页面,表以及对应的mapper,Service、controller等

atjiu commented 5 years ago

@Liuguozhu 你先试试看从master上下载最新的源码, 看能正常启动不?

因为我部署的 demo.yiiu.co 和平时开发都没有碰到这个问题, 我还真不知道怎么解决..

Liuguozhu commented 5 years ago

好,我试试,再找找看有没有解决办法

Liuguozhu commented 5 years ago

@tomoya92 我试了你demo演示后台,记住我功能也没生效,每次都要输入账号密码登录

Liuguozhu commented 5 years ago

@tomoya92 我试了你demo演示后台,记住我功能也没生效,每次都要输入账号密码登录

就是这个地址:https://demo.yiiu.co/adminlogin 你看看是不是也是报错导致的

atjiu commented 5 years ago

@tomoya92 我试了你demo演示后台,记住我功能也没生效,每次都要输入账号密码登录

就是这个地址:https://demo.yiiu.co/adminlogin 你看看是不是也是报错导致的

我部署的这个后台登录没有问题呀

Liuguozhu commented 5 years ago

我下了最新的代码,没做任何改动,启动后,登录也会报这个错,可以正常登录,就是“记不住我”

Liuguozhu commented 5 years ago

解决报错问题: co.yiiu.pybbs.config.ShiroConfig.rememberMeManager(); 修改如下:

 @Bean
  @DependsOn("mybatisPlusConfig")
  public CookieRememberMeManager rememberMeManager() {
    //System.out.println("ShiroConfiguration.rememberMeManager()");
    CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
    cookieRememberMeManager.setCookie(rememberMeCookie());
    //rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)
    cookieRememberMeManager.setCipherKey(Base64.encode("pybbs best!".getBytes()));
//    cookieRememberMeManager.setCipherKey(Base64.decode("wGiHplamyXlVB11UXWol8g=="));
    return cookieRememberMeManager;
  }

主要是CipherKey的长度导致的,24位修改为16位就不报错了

  public static void main(String[] args) {
    System.out.println(Base64.encode("pybbs is the best!".getBytes()).length);
    System.out.println(Base64.encode("pybbs best!".getBytes()).length);
  }

执行结果

24
16
Liuguozhu commented 5 years ago

这个只是不报错了,但是,重新打开浏览器,还是要重新输入账号密码重新登录

atjiu commented 5 years ago

@Liuguozhu 为啥我没有动代码的情况下也没有问题呢? 挺奇怪的..

另外记住我功能我测试的时候看到cookie里有readme信息, 登录完成后, 重启服务再次访问后台也是没有问题的, 但这个时效是多久我没有做测试, 感觉挺短的

Liuguozhu commented 5 years ago

@tomoya92 我看你那个时间代码里设置的是5分钟,但是我是在一分钟之内试的。,服务器没重启,只是关闭浏览器重新打开,就不行。重启服务器更不行。还不如借助浏览器的记住密码。

atjiu commented 4 years ago

@Liuguozhu

这个只是不报错了,但是,重新打开浏览器,还是要重新输入账号密码重新登录

这个问题终于解决了,shiro里内置的几个filter里

我之前把 /admin/** 都配置成了 authc ,导致了rememberMe没有生效的机会,现在修改好了,详见:https://github.com/tomoya92/pybbs/commit/7cdac7b70f164963d9caf4e7b86fc5b255862986