1. 程式人生 > >springboot整合shiro本地執行沒問題,部署到ubutun伺服器報錯org.apache.shiro.UnavailableSecurityManagerException: 求助

springboot整合shiro本地執行沒問題,部署到ubutun伺服器報錯org.apache.shiro.UnavailableSecurityManagerException: 求助

最近學習springboot框架,整合了shiro許可權,本地執行沒毛病,但是蛋疼了,釋出到伺服器,訪問都會報錯:

org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton.  This is an invalid application configuration.
at org.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:123)
at org.apache.shiro.subject.Subject$Builder.<init>(Subject.java:627)
at org.apache.shiro.SecurityUtils.getSubject(SecurityUtils.java:56)
at com.example.demo.session.SessionBuild.getLoginUser(SessionBuild.java:99)
at com.example.demo.interceptor.loginInterceptor.preHandle(loginInterceptor.java:26)
at org.springframework.web.servlet.HandlerExecutionChain.applyPreHandle(HandlerExecutionChain.java:136)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:986)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:728)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:472)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:395)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:316)
at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:395)
at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:254)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:177)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)

2018-06-20 17:05:05.207  WARN 9087 --- [nio-8888-exec-2] .m.m.a.ExceptionHandlerExceptionResolver : Failed to invoke @ExceptionHandler method: public java.lang.Object com.example.demo.exception.GlobalExceptionHandler.RuntimeExceptionHandler(javax.servlet.http.HttpServletRequest,java.lang.RuntimeException)

很是無奈,shiro配置如下:

@Configuration
public class ShiroConfig {
    /**
     * LifecycleBeanPostProcessor,這是個DestructionAwareBeanPostProcessor的子類,
     * 負責org.apache.shiro.util.Initializable型別bean的生命週期的,初始化和銷燬。
     * 主要是AuthorizingRealm類的子類,以及EhCacheManager類。
     */
@Bean(name = "lifecycleBeanPostProcessor")
    public 
LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } /** * HashedCredentialsMatcher,這個類是為了對密碼進行編碼的, * 防止密碼在資料庫裡明碼儲存,當然在登陸認證的時候, * 這個類也負責對form裡輸入的密碼進行編碼。 */ @Bean(name = "hashedCredentialsMatcher") public HashedCredentialsMatcher hashedCredentialsMatcher() { HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher(); credentialsMatcher.setHashAlgorithmName("MD5"); credentialsMatcher.setHashIterations(2); credentialsMatcher.setStoredCredentialsHexEncoded(true); return credentialsMatcher; } /**ShiroRealm,這是個自定義的認證類,繼承自AuthorizingRealm, * 負責使用者的認證和許可權的處理,可以參考JdbcRealm的實現。 */ @Bean(name = "shiroRealm") @DependsOn("lifecycleBeanPostProcessor") public ShiroRealm shiroRealm() { ShiroRealm realm = new ShiroRealm(); // realm.setCredentialsMatcher(hashedCredentialsMatcher()); return realm; } // /** // * EhCacheManager,快取管理,使用者登陸成功後,把使用者資訊和許可權資訊快取起來, // * 然後每次使用者請求時,放入使用者的session中,如果不設定這個bean,每個請求都會查詢一次資料庫。 // */ // @Bean(name = "ehCacheManager") // @DependsOn("lifecycleBeanPostProcessor") // public EhCacheManager ehCacheManager() { // return new EhCacheManager(); // } /** * SecurityManager,許可權管理,這個類組合了登陸,登出,許可權,session的處理,是個比較重要的類。 // */ @Bean(name = "securityManager") public DefaultWebSecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(shiroRealm()); // securityManager.setCacheManager(ehCacheManager()); return securityManager; } /** * ShiroFilterFactoryBean,是個factorybean,為了生成ShiroFilter。 * 它主要保持了三項資料,securityManager,filters,filterChainDefinitionManager。 */ @Bean(name = "shiroFilter") public ShiroFilterFactoryBean shiroFilterFactoryBean() { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager()); Map<String, Filter> filters = new LinkedHashMap<>(); LogoutFilter logoutFilter = new LogoutFilter(); logoutFilter.setRedirectUrl("/login"); // filters.put("logout",null); shiroFilterFactoryBean.setFilters(filters); Map<String, String> filterChainDefinitionManager = new LinkedHashMap<String, String>(); filterChainDefinitionManager.put("/logout", "logout"); filterChainDefinitionManager.put("/user/**", "authc,roles[ROLE_USER]");//使用者為ROLE_USER 角色可以訪問。由使用者角色控制使用者行為。 filterChainDefinitionManager.put("/events/**", "authc,roles[ROLE_ADMIN]"); // filterChainDefinitionManager.put("/user/edit/**", "authc,perms[user:edit]");// 這裡為了測試,固定寫死的值,也可以從資料庫或其他配置中讀取,此處是用許可權控制 filterChainDefinitionManager.put("/**", "anon"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionManager); shiroFilterFactoryBean.setSuccessUrl("/"); shiroFilterFactoryBean.setUnauthorizedUrl("/403"); return shiroFilterFactoryBean; } /** * DefaultAdvisorAutoProxyCreator,Spring的一個bean,由Advisor決定對哪些類的方法進行AOP代理。 */ @Bean @ConditionalOnMissingBean public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator(); defaultAAP.setProxyTargetClass(true); return defaultAAP; } /** * AuthorizationAttributeSourceAdvisor,shiro裡實現的Advisor類, * 內部使用AopAllianceAnnotationsAuthorizingMethodInterceptor來攔截用以下註解的方法。 */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() { AuthorizationAttributeSourceAdvisor aASA = new AuthorizationAttributeSourceAdvisor(); aASA.setSecurityManager(securityManager()); return aASA; } }
也有自定義攔截器

求大神指點。。。。