2019-10-29 11:39:06.809 WARN 14068 --- [nio-8081-exec-1] o.a.shiro.authc.AbstractAuthenticator : Authentication failed for token submission [org.apache.shiro.authc.UsernamePasswordToken - admin, rememberMe=false]. Possible unexpected error? (Typical or expected login exceptions should extend from AuthenticationException). java.lang.NullPointerException: null at com.example.shiro.config.CustomRealm.doGetAuthenticationInfo(CustomRealm.java:60) ~[classes/:na] at org.apache.shiro.realm.AuthenticatingRealm.getAuthenticationInfo(AuthenticatingRealm.java:571) ~[shiro-core-1.4.1.jar:1.4.1] at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doSingleRealmAuthentication(ModularRealmAuthenticator.java:180) ~[shiro-core-1.4.1.jar:1.4.1] at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doAuthenticate(ModularRealmAuthenticator.java:267) ~[shiro-core-1.4.1.jar:1.4.1] at org.apache.shiro.authc.AbstractAuthenticator.authenticate(AbstractAuthenticator.java:198) ~[shiro-core-1.4.1.jar:1.4.1] at org.apache.shiro.mgt.AuthenticatingSecurityManager.authenticate(AuthenticatingSecurityManager.java:106) [shiro-core-1.4.1.jar:1.4.1] at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:275) [shiro-core-1.4.1.jar:1.4.1] at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:260) [shiro-core-1.4.1.jar:1.4.1] at com.example.shiro.controller.UserController.login(UserController.java:32) [classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_211] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_211] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_211] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_211] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) [spring-web-5.2.0.RELEASE.jar:5.2.0.RELEASE] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) [spring-web-5.2.0.RELEASE.jar:5.2.0.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) [spring-webmvc-5.2.0.RELEASE.jar:5.2.0.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888) [spring-webmvc-5.2.0.RELEASE.jar:5.2.0.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) [spring-webmvc-5.2.0.RELEASE.jar:5.2.0.RELEASE] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) [spring-webmvc-5.2.0.RELEASE.jar:5.2.0.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) [spring-webmvc-5.2.0.RELEASE.jar:5.2.0.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) [spring-webmvc-5.2.0.RELEASE.jar:5.2.0.RELEASE] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.2.0.RELEASE.jar:5.2.0.RELEASE] at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) [spring-webmvc-5.2.0.RELEASE.jar:5.2.0.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:660) [tomcat-embed-core-9.0.27.jar:9.0.27] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) [spring-webmvc-5.2.0.RELEASE.jar:5.2.0.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) [tomcat-embed-core-9.0.27.jar:9.0.27]
上面出現的NPE , at com.example.shiro.config.CustomRealm.doGetAuthenticationInfo(CustomRealm.java:60) ~[classes/:na] 是String password = userService.getPasswordByUsername(userName); 這行代碼java
public class CustomRealm extends AuthorizingRealm { @Autowired private RoleService roleService; @Autowired private RolePermissionService rolePermissionService; @Autowired private UserService userService; //認證 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //從主體傳過來的認證信息中,獲取用戶名 String userName = (String)authenticationToken.getPrincipal(); //經過用戶名去到數據庫中獲取憑證 String password = userService.getPasswordByUsername(userName); if (StringUtils.isEmpty(password)) { return null; } SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userName, password, "costomRealm"); //設置鹽salt simpleAuthenticationInfo.setCredentialsSalt(ByteSource.Util.bytes("pyy")); return simpleAuthenticationInfo; } }
@Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); CustomRealm customRealm = new CustomRealm(); //加密配置 HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(); //設置加密算法名稱 matcher.setHashAlgorithmName("md5"); //設置加密次數 matcher.setHashIterations(1); customRealm.setCredentialsMatcher(matcher); //設置Realm securityManager.setRealm(customRealm); return securityManager; }
報NPE, 說明userService沒有注入進來,爲何?web
由於shiro 的realm自己至關於過濾器,而在登陸訪問時會先走過濾器,再執行service注入,這就會出現尚未進行service注入,已經再realm中調用注入的對象,因此就會出現上述現象算法
@Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //設置Realm securityManager.setRealm(customRealm()); return securityManager; } @Bean public CustomRealm customRealm() { CustomRealm customRealm = new CustomRealm(); //加密配置 HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(); //設置加密算法名稱 matcher.setHashAlgorithmName("md5"); //設置加密次數 matcher.setHashIterations(1); customRealm.setCredentialsMatcher(matcher); return customRealm; }