2016-08-13 70 views
2

我已將Spring Shiro與Spring Boot與Spring Data JPA集成在一起。 Spring Boot項目位於this GitHub倉庫中。Shiro與Springboot集成

問題是,當我運行,並嘗試驗證應用程序,我碰到下面的錯誤

roleAdmin.getId() 1: null 
roleAdmin.getId() 2: 3 
Current user is not authenticated. 
2016-08-13 09:49:45.715 WARN 10528 --- [lication Thread] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: S0022 
2016-08-13 09:49:45.716 ERROR 10528 --- [lication Thread] o.h.engine.jdbc.spi.SqlExceptionHelper : Column 'id' not found. 
Authentication failed for token submission [org.apache.shiro.authc.UsernamePasswordToken - yunus, rememberMe=false]. Possible unexpected error? (Typical or expected login exceptions should extend from AuthenticationException). 

它完全不能進行身份驗證,我設法創造this回購來闡述我的問題。一探究竟。

解決方案和批評是高度可以接受的。

更新

如果需要任何額外的信息來澄清我的問題,只是問

回答

1

你的錯誤消息指示的問題,這在於你的用戶信息庫的@Query定義:

@Query(value = "SELECT u.username FROM users u WHERE u.username = ?1", nativeQuery = true) 
User findByUsername(String username); 

正如你所看到的,你只選擇用戶名,而不是選擇每一列。既然你使用Spring數據JPA,你並不真正需要的@Query可言,這是不夠的,只是說:

User findByUsername(String username); 

你的其他問題,但是,您如何在自定義領域比較密碼。從DB來的密碼將被加密,這意味着你不能只是說

user.getPassword().equals(new String(upat.getPassword())) 

你必須通過調用其passwordsMatch方法和使用DefaultPasswordService密碼比較,因爲you'e只是驗證自己paswords ,你應該在你的領域使用AllowAllCredentialsMatcher

public class CustomSecurityRealm extends AuthorizingRealm { 

    @Autowired 
    private UserManagerService userManager; 

    @Autowired 
    private DefaultPasswordService passwordService; 

    public CustomSecurityRealm() { 
     this(new AllowAllCredentialsMatcher()); 
    } 

    public CustomSecurityRealm(final CredentialsMatcher matcher) { 
     super(matcher); 
    } 

    @Override 
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { 
     // remains the same 
    } 

    @Override 
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { 
     UsernamePasswordToken upat = (UsernamePasswordToken) token; 
     User user = userManager.findByUsername(upat.getUsername());        
     if(user != null && passwordService.passwordsMatch(upat.getPassword(), user.getPassword())) { 
      return new SimpleAuthenticationInfo(user, user.getPassword(), getName()); 
     } 
     else { 
      throw new AuthenticationException("Invalid username/password combination!"); 
     } 
    } 
} 
+0

它現在有效,謝謝你。這個問題一直困擾着我。 –

+1

太棒了!順便說一句,你發佈的可運行示例幫助了很多,花了大約5分鐘來追蹤這個問題,如果只有更多的人會這樣做:) –