关于 项目中用到shiro如何通过token鉴权登录,模拟登录,代码直接登录的问题!

1.今天遇到了一个棘手的问题,在此写下博客记录下来,用于提醒自己,以及帮助以后会遇到这样的问题的人

shiro框架中如何通过用户名密码在代码中直接登录?

首先在网上找了下,找到了这种方式:

Subject currentUser = SecurityUtils.getSubject();
				UsernamePasswordToken token = new UsernamePasswordToken(username,password, false,request.getRemoteAddr());
				currentUser.login(token);

由于自己的项目中登录时还要判断用户角色所以,用了UsernamePasswordUsertypeToken.java,代码如下

import org.apache.shiro.authc.HostAuthenticationToken;
import org.apache.shiro.authc.RememberMeAuthenticationToken;
/**
 * 参考org.apache.shiro.authcUsernamePasswordToken,增加了用户类型参数
 * @author caihz
 * @see org.apache.shiro.authcUsernamePasswordToken
 */
public class UsernamePasswordUsertypeToken implements HostAuthenticationToken, RememberMeAuthenticationToken {
	/**
     * 用户名
     */
    private String username;

    /**
     * 密码, in char[] format
     */
    private char[] password;

    /**
     * 是否记住我
     * 默认值:<code>false</code>
     */
    private boolean rememberMe = false;

    /**
     * 主机名称或ip
     */
    private String host;
    
    /**
     * 用户类型
     */
    private String usertype;

    public UsernamePasswordUsertypeToken() {
    }

    /**
     * 构造方法
     * @param username 用户名
     * @param password 密码(char[])
     * @param rememberMe 是否记住我
     * @param host 主机或ip
     * @param usertype 用户类型
     */
    public UsernamePasswordUsertypeToken(final String username, final char[] password,
                                 final boolean rememberMe, final String host, final String usertype) {

        this.username = username;
        this.password = password;
        this.rememberMe = rememberMe;
        this.host = host;
        this.usertype = usertype;
    }
    
    /**
     * 构造方法
     * @param username 用户名
     * @param password 密码(String)
     * @param rememberMe 是否记住我
     * @param host 主机或ip
     * @param usertype 用户类型
     */
    public UsernamePasswordUsertypeToken(final String username, final String password,
                                 final boolean rememberMe, final String host, final String usertype) {
        this(username, password != null ? password.toCharArray() : null, rememberMe, host, usertype);
    }

	public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public char[] getPassword() {
        return password;
    }
    public void setPassword(char[] password) {
        this.password = password;
    }

    /**
     * Simply returns {@link #getUsername() getUsername()}.
     *
     * @return the {@link #getUsername() username}.
     * @see org.apache.shiro.authc.AuthenticationToken#getPrincipal()
     */
    public Object getPrincipal() {
        return getUsername();
    }

    /**
     * Returns the {@link #getPassword() password} char array.
     *
     * @return the {@link #getPassword() password} char array.
     * @see org.apache.shiro.authc.AuthenticationToken#getCredentials()
     */
    public Object getCredentials() {
        return getPassword();
    }
    public String getHost() {
        return host;
    }
    public void setHost(String host) {
        this.host = host;
    }
    public boolean isRememberMe() {
        return rememberMe;
    }
    public void setRememberMe(boolean rememberMe) {
        this.rememberMe = rememberMe;
    }
    public String getUsertype() {
		return usertype;
	}
	public void setUsertype(String usertype) {
		this.usertype = usertype;
	}

	/**
	 * 清除数据
	 * 密码如果不为空,设置成0x00
	 */
    public void clear() {
        this.username = null;
        this.host = null;
        this.rememberMe = false;
        this.usertype = null;

        if (this.password != null) {
            for (int i = 0; i < password.length; i++) {
                this.password[i] = 0x00;
            }
            this.password = null;
        }

    }

    /**
     * 重写toString方法
     */
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getName());
        sb.append(" - ");
        sb.append(username);
        sb.append(", usertype=").append(usertype);
        sb.append(", rememberMe=").append(rememberMe);
        if (host != null) {
            sb.append(" (").append(host).append(")");
        }
        return sb.toString();
    }


}

将上述代码修改了下,如下:

Subject currentUser = SecurityUtils.getSubject();
				UsernamePasswordUsertypeToken token = new UsernamePasswordUsertypeToken(user.getPhone(),user.getLoginPass(), false,req.getRemoteAddr(),role);
				currentUser.login(token);

这里controller层里的代码差不多了,接下来要修改shiro里的配置以及Realm

配置如下:

<!-- 和教育的Realm 2015-9-10-->
	<bean id="shiroAndEduRealm" class="com.linkage.educloud.ucenter.learn.service.ShiroAndEduRealm">
		<!-- property name="accountService" ref="accountService"/ -->
		<!-- 获得的用户密码已经是加密过的了,验证的时候不用加密验证了-->
	<!-- <property name="credentialsMatcher" ref="credentialsMatcher"/> -->
		<property name="authenticationTokenClass" value="com.linkage.educloud.ucenter.login.shiro.UsernamePasswordUsertypeToken"/>
	</bean>

<bean id="authenticator" class="com.linkage.educloud.ucenter.login.shiro.FirstSuccessfulModularRealmAuthenticator">
		<property name="authenticationStrategy" ref="firstSuccessfulStrategy"/>
		<property name="realms">
			<list>
                <ref bean="shiroDbRealm"/>
                <ref bean="shiroXxtRealm"/>
                <ref bean="shiroAndEduRealm"/>
            </list>
		</property>
	</bean>

com.linkage.educloud.ucenter.learn.service.ShiroAndEduRealm.java代码如下:

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.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.linkage.educloud.api.ucenter.service.Uc2XXTIfaceService;
import com.linkage.educloud.base.util.StringUtil;
import com.linkage.educloud.domain.ucenter.login.UcenterLoginUser;
import com.linkage.educloud.ucenter.login.service.UcenterLoginService;
import com.linkage.educloud.ucenter.login.shiro.UsernamePasswordUsertypeToken;

/**
 * 登录Realm
 * @author caihz
 *
 */
public class ShiroAndEduRealm extends AuthorizingRealm {
	final static Logger log = LoggerFactory.getLogger(ShiroAndEduRealm.class);
	
	@Autowired
	private UcenterLoginService ucenterLoginService;

	@Autowired
	private Uc2XXTIfaceService xxtService;
	
	/**
	 * 登录认证回调函数,登录时调用.
	 * @param authcToken 登录页面参数,用户名和密码等
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		UsernamePasswordUsertypeToken token = (UsernamePasswordUsertypeToken) authcToken;
		String username = token.getUsername();
		if (username == null){
			throw new AccountException("账号不能为空");
		}
		//如果用户中心没有用户,则请求校讯通登录接口并查询用户中心对应的用户
		String password = String.valueOf(token.getPassword());
		//password = StringUtil.md5(password);
		password = password.toLowerCase();
		UcenterLoginUser user = ucenterLoginService.findUserByXxt(token.getUsername(), password, token.getUsertype());
		if (user != null){
			return new SimpleAuthenticationInfo(user, user.getLoginPass(), getName());
		}else {
			return null;
		}
		
	}

	/**
	 * 登录认证通过后的权限查询函数, 由于目前用户中心前台页面不需要权限控制,所以没写,以后如果需要可扩展
	 * 
	 * @see org.apache.shiro.authz.AuthorizationInfo
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

		return info;
	}
}

这下可终于解决了用户直接通过token鉴权登录的问题了。

例子:

@RequestMapping("/test")
	public String test(HttpServletRequest request){
		Subject subject = SecurityUtils.getSubject();
	       // subject.login(new UsernamePasswordToken(user.getPhone(), user.getLoginPass()));
			//UsernamePasswordUsertypeToken up = new UsernamePasswordUsertypeToken("13816005001", "123456aA1", false, null, "3");
			UsernamePasswordUsertypeToken up = new UsernamePasswordUsertypeToken("20212414", "4d45acd6c95faab86980ebbae7cad57c", false, request.getRemoteAddr(), "1");
		//UsernamePasswordUsertypeToken up = new UsernamePasswordUsertypeToken("20212414", "bLaP7@3U", false, request.getRemoteAddr(), "1");    
		subject.login(up);
		System.out.println("登录成功!");
		return "redirect:/ucenter/index/index";
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值