我正在用Shiro使用Spring Boot進行身份驗證來構建REST API。當我嘗試在領域代碼中自動裝入存儲庫時,我收到NullPointerException。在其他位置自動裝配存儲庫不會產生此錯誤。自動裝配類中的空指針異常
這裏是我的授權境界:
@Component
public class CCDAuthorizingRealm extends AuthorizingRealm {
@Autowired
private UserRepository userRepository;
public CCDAuthorizingRealm() { }
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
AuthenticationInfo authenticationInfo = null;
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
String username = token.getUsername();
User user = null;
try {
user = userRepository.findByUsername(username);
} catch (Exception e) {
e.printStackTrace(System.err);
}
if (user != null) {
authenticationInfo = new SimpleAuthenticationInfo(
new SimplePrincipalCollection(username, username),
user.getPassword());
}
return authenticationInfo;
}
....
}
當我嘗試調用findByUsername()方法時發生的異常。
以下是我注入的存儲庫的代碼。
@Transactional(readOnly=true)
@RepositoryRestResource(collectionResourceRel="users", path="users")
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
User findByUsername(@Param("user") String user);
....
}
爲了測試,我將庫自動裝入我的應用程序類並打印結果,並且沒有發生錯誤。爲了完整性,這裏是代碼來表明:
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
public UserRepository userRepository;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... strings) {
System.out.println("\nServer up\n");
User user = userRepository.findOne(new Long(1));
System.out.println(user.getUsername());
}
}
任何幫助,非常感謝。
編輯
至於我可以告訴這個問題不是一個重複,並回答其他問題不解決我的問題。我正在注入bean並通知組件的IoC容器,但自動裝配仍然導致NPE。
使用範圍並沒有幫助,因爲我只需要單個服務對象。可配置標籤不是必需的,因爲我是自動裝配的,不需要創建新的對象。
UPDATE
這裏是我打電話CCDAuthorizingRealm。我是使用Shiro的新手,但我確信這是正確的。
@RestController
@RequestMapping(produces="application/json")
public class AuthenticationController {
CCDAuthorizingRealm realm = new CCDAuthorizingRealm();
SecurityManager sm = new DefaultSecurityManager(realm);
public AuthenticationController() { }
/**
* Authenticate user with supplied credentials
*
* @param login - credentials
* @return success or failure message
*/
@RequestMapping(value = "/login", method = RequestMethod.POST, consumes="application/json")
public String login(@RequestBody LoginInfo login) {
String response;
UsernamePasswordToken token = new UsernamePasswordToken(
login.getUsername(),
login.getPassword(),
false);
try {
SecurityUtils.setSecurityManager(sm);
Subject currentUser = SecurityUtils.getSubject();
if (currentUser.isAuthenticated()) {
currentUser.logout();
}
currentUser.login(token);
response = token.toString();
} catch (AuthenticationException e) {
response = "Error: Incorrect username or password";
}
return response;
}
}
我目前嘗試在控制器中創建我的領域的新實例。
@Autowired
CCDAuthorizingRealm realm;
SecurityManager sm = new DefaultSecurityManager(realm);
初始化安全管理器的時候,因爲它會抱怨境界是零,我會得到一個運行時錯誤:當我嘗試我這樣做是因爲。我不明白爲什麼領域爲空,但是,因爲它被註釋爲一個組件。也許這是我的問題的根源。
你沒有顯示你將CCDAuthorizingRealm注入其調用者的位置。 – chrylis
不,我說當注入到Application類中時,存儲庫方法可以正常工作。當我嘗試將它自動裝入CCDAuthorizingRealm類時,會出現NPE。這個領域是用@Component註釋的,所以,據我所知,應用程序應該找到它,因爲Spring Boot包含了組件掃描。 –
實現'UserRepository'接口的Bean是否不應該有'@ Component'註解? –