Я использую 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());
        }

} 
2
user510783 28 Дек 2011 в 19:43

1 ответ

Нет лучшего источника ответов, чем javadoc Широ. doGetAuthenticationInfo() возвращает AuthenticationInfo. SimpleAuthenticationInfo — это реализация AuthenticationInfo. Subject "представляет состояние и операции безопасности для одного пользователя приложения», как указано в javadoc, поэтому нет, мы не устанавливаем тему здесь, но фреймворк повторно устанавливает ее для каждого запроса. Назначение (простой)AuthenticationInfo должен представлять «сохраненную информацию об учетной записи субъекта (также известного как пользователь), относящуюся только к процессу аутентификации / входа в систему». Область отвечает за создание AuthenticationInfo (если пользователь найден), а затем CredentialsMatcher сравнивает AuthenticationToken с AuthenticationInfo, чтобы определить, действительны ли данные учетные данные или нет.

Вы не объясняете, как вы «застряли», но если ваш findByUsername() возвращает соответствующий UserAccount, у вас, вероятно, не настроен правильный CredentialsMatcher. Возможно, вам нужно установите HashedCredentialsMatcher для вашей области.

4
Kalle 29 Дек 2011 в 20:22