2015-05-15 64 views
0

我正在用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); 

初始化安全管理器的時候,因爲它會抱怨境界是零,我會得到一個運行時錯誤:當我嘗試我這樣做是因爲。我不明白爲什麼領域爲空,但是,因爲它被註釋爲一個組件。也許這是我的問題的根源。

+0

你沒有顯示你將CCDAuthorizingRealm注入其調用者的位置。 – chrylis

+0

不,我說當注入到Application類中時,存儲庫方法可以正常工作。當我嘗試將它自動裝入CCDAuthorizingRealm類時,會出現NPE。這個領域是用@Component註釋的,所以,據我所知,應用程序應該找到它,因爲Spring Boot包含了組件掃描。 –

+0

實現'UserRepository'接口的Bean是否不應該有'@ Component'註解? –

回答

1

我發現了我的問題的答案。以下是我的applicationContext.xml文件中的內容:

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> 
    <property name="securityManager" ref="securityManager" /> 
    <property name="loginUrl" value="/login" /> 
    <property name="successUrl" value="/home" /> 
    <property name="unauthorizedUrl" value="/login" /> 
    <property name="filterChainDefinitions"> 
     <value> 
      /login = authc 
     </value> 
    </property> 
</bean> 

此配置的問題是登錄URL被過濾掉了。此修復程序是簡單的值更改爲家,像這樣:

<value> 
    /home = authc 
</value> 

我相信這將濾波器背後的家庭地址,來代替。