2

私は Tapestry5 を使用しており、セキュリティには apache shiro を使用しています。データベーステーブルからユーザーを認証することに行き詰まっています。

この関数 doGetAuthenticationInfo() では、サブジェクトを設定する必要はありませんか?

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

1 に答える 1

4

Shiro の javadocほど優れた回答ソースはありません。doGetAuthenticationInfo() は AuthenticationInfo を返します。SimpleAuthenticationInfo は AuthenticationInfo の実装です。サブジェクトは、javadoc が述べているように、「単一のアプリケーション ユーザーの状態とセキュリティ操作を表す」ため、ここではサブジェクトを設定しませんが、フレームワークはリクエストごとにサブジェクトを繰り返し設定します。(簡易) AuthenticationInfoの目的「認証/ログインプロセスのみに関連するサブジェクト(別名ユーザー)の保存されたアカウント情報」を表すことです。レルムの役割は、AuthenticationInfo (ユーザーが見つかった場合) を作成することであり、CredentialsMatcher は AuthenticationToken を AuthenticationInfo と比較して、指定された資格情報が有効かどうかを判断します。

どのように「動けなくなった」かは説明しませんが、findByUsername() が適切な UserAccount を返すと仮定すると、おそらく適切な CredentialsMatcher が構成されていません。おそらく、 HashedCredentialsMatcher を realmに設定する必要があります。

于 2011-12-29T16:22:09.030 に答える