2011-12-28 105 views
2

我使用Tapestry5和apache shiro安全。 我堅持從數據庫表認證用戶。掛毯shiro安全認證

在這個函數doGetAuthenticationInfo()中我們不需要設置Subject嗎?

SimpleAuthenticationInfo的用途是什麼?

package com.kids.crm.services; 

import java.util.HashSet; 
import java.util.Set; 

import org.apache.shiro.SecurityUtils; 
import org.apache.shiro.authc.AccountException; 
import org.apache.shiro.authc.AuthenticationException; 
import org.apache.shiro.authc.AuthenticationInfo; 
import org.apache.shiro.authc.AuthenticationToken; 
import org.apache.shiro.authc.SimpleAuthenticationInfo; 
import org.apache.shiro.authc.UnknownAccountException; 
import org.apache.shiro.authc.UsernamePasswordToken; 
import org.apache.shiro.authz.AuthorizationException; 
import org.apache.shiro.authz.AuthorizationInfo; 
import org.apache.shiro.authz.SimpleAuthorizationInfo; 
import org.apache.shiro.realm.AuthorizingRealm; 
import org.apache.shiro.subject.PrincipalCollection; 
import org.apache.shiro.subject.Subject; 
import org.apache.shiro.util.SimpleByteSource; 
import org.apache.tapestry5.ioc.annotations.Inject; 
import org.springframework.beans.factory.annotation.Autowired; 

import com.kids.crm.dao.DatabaseDao; 
import com.kids.crm.dao.UserAccountDao; 
import com.kids.crm.dao.impl.UserAccountDaoImpl; 
import com.kids.crm.db.Role; 
import com.kids.crm.db.UserAccount; 


public class UserRealm extends AuthorizingRealm { 
     @Inject UserAccountDao userAccountDao; 
     public UserRealm() { 
       setName("localaccounts"); 
       setAuthenticationTokenClass(UsernamePasswordToken.class); 
     } 

     private UserAccount findByUsername(String userName) { 
       return (UserAccount) userAccountDao.getUserByUserName(userName); 
     } 

     @Override 
     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { 
       //Subject currentUser = SecurityUtils.getSubject(); 
       UsernamePasswordToken upToken = (UsernamePasswordToken) token; 

         String username = upToken.getUsername(); 
         upToken.setRememberMe(true); 
         // Null username is invalid 
         if (username == null) { throw new AccountException("Null usernames are not allowed by this realm."); } 
         UserAccount user = findByUsername(username); 

       return new SimpleAuthenticationInfo(username, user.getEncodedPassword(), new SimpleByteSource(user.getPasswordSalt()), getName()); 
     } 

} 

回答

4

沒有比Shiro's javadoc更好的答案來源。 doGetAuthenticationInfo()返回一個AuthenticationInfo。 SimpleAuthenticationInfo是AuthenticationInfo的一個實現。 Subject「代表單個應用程序用戶的狀態和安全操作」,因爲javadoc狀態,所以不,我們不在這裏設置主題,但框架爲每個請求重複設置它。 (簡單)AuthenticationInfo的目的是爲了表示「僅與認證/登錄過程相關的主題(即用戶)存儲的帳戶信息」。領域的責任是創建AuthenticationInfo(如果找到用戶),然後CredentialsMatcher將AuthenticationToken與AuthenticationInfo進行比較,以確定給定憑證是否有效。

你沒有解釋你是如何「卡住」的,但假設你的findByUsername()返回一個合適的UserAccount,你可能沒有配置正確的CredentialsMatcher。也許你需要set a HashedCredentialsMatcher to your realm