user510783
user510783

Reputation: 275

tapestry shiro security authentication

I am using Tapestry5, and apache shiro for security. I am stuck with authenticating user from database table.

In this function doGetAuthenticationInfo() don't we need to set the Subject?

What is the purpose of 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());
        }

} 

Upvotes: 2

Views: 1602

Answers (1)

Kalle
Kalle

Reputation: 2257

No better source for answers than Shiro's javadoc. doGetAuthenticationInfo() returns an AuthenticationInfo. A SimpleAuthenticationInfo is an implementation of AuthenticationInfo. Subject "represents state and security operations for a single application user" as the javadoc states, so no, we don't set the subject here, but the framework repeatedly sets it up for each request. The purpose of the (Simple)AuthenticationInfo is to represent "a Subject's (aka user's) stored account information relevant to the authentication/log-in process only". The realm's responsibility is to create an AuthenticationInfo (if the user is found) and the CredentialsMatcher then compares the AuthenticationToken to AuthenticationInfo to detemine whether the given credentials are valid or not.

You don't explain how you "are stuck", but assuming your findByUsername() returns an appropriate UserAccount, you probably don't have the right CredentialsMatcher configured. Perhaps you need to set a HashedCredentialsMatcher to your realm.

Upvotes: 4

Related Questions