NutzCN Logo
问答 跟着手册来的,在整合shiro的时候报错了,找问题找了好久了,毫无头绪。。。
发布于 2749天前 作者 qq_b61182f1 1601 次浏览 复制 上一个帖子 下一个帖子
标签:

User类的代码

package net.wendal.nutzbook.bean;

import java.util.List;

import org.nutz.dao.entity.annotation.ColDefine;
import org.nutz.dao.entity.annotation.Column;
import org.nutz.dao.entity.annotation.Id;
import org.nutz.dao.entity.annotation.ManyMany;
import org.nutz.dao.entity.annotation.Name;
import org.nutz.dao.entity.annotation.One;
import org.nutz.dao.entity.annotation.Table;

@Table("t_user")
public class User extends BasePojo{
	@Id
	private int id;
	@Name
	@Column
	private String name;
	@Column("passwd")
	@ColDefine(width=128)
	private String password;
	@Column
	private String salt;
	@Column
	private boolean locked;
	
	@ManyMany(from="u_id",relation="t_user_role",target=Role.class,to="role_id")
	protected List<Role> roles;
	@ManyMany(from="u_id",relation="t_user_permission",target=Permission.class,to="permission_id")
	protected List<Permission> permissions;
	@One(target=UserProfile.class,field="id",key="userId")
	protected UserProfile profile;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getSalt() {
		return salt;
	}
	public void setSalt(String salt) {
		this.salt = salt;
	}
	public UserProfile getProfile() {
		return profile;
	}
	public void setProfile(UserProfile profile) {
		this.profile = profile;
	}
	public boolean isLocked() {
		return locked;
	}
	public void setLocked(boolean locked) {
		this.locked = locked;
	}
	public List<Role> getRoles() {
		return roles;
	}
	public void setRoles(List<Role> roles) {
		this.roles = roles;
	}
	public List<Permission> getPermissions() {
		return permissions;
	}
	public void setPermissions(List<Permission> permissions) {
		this.permissions = permissions;
	}
	
	
}

NutDaoRealm类的代码

package net.wendal.nutzbook.shiro.realm;


import net.wendal.nutzbook.bean.Permission;
import net.wendal.nutzbook.bean.Role;
import net.wendal.nutzbook.bean.User;
import net.wendal.nutzbook.util.Toolkit;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAccount;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.integration.shiro.CaptchaUsernamePasswordToken;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.mvc.Mvcs;

@IocBean
public class NutDaoRealm extends AuthorizingRealm{

	@Inject protected Dao dao;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		if(principals==null){
			throw new AuthenticationException("PrincipalCollection method argument cannot be null.");
		}
		
		int userId = (Integer)principals.getPrimaryPrincipal();
		User user=dao().fetch(User.class,userId);
		if(user==null){
			return null;
		}
		if(user.isLocked()){
			throw new LockedAccountException("Account [" + user.getName() + "] is locked.");
		}
		
		SimpleAuthorizationInfo auth= new SimpleAuthorizationInfo();
		user=dao().fetchLinks(user, null);
		if(user.getRoles()!=null){
			dao().fetchLinks(user.getRoles(), null);
			for(Role role:user.getRoles()){
				auth.addRole(role.getName());
				if(role.getPermissions()!=null){
					for(Permission p:role.getPermissions()){
						auth.addStringPermission(p.getName());
					}
				}
			}
		}
		
		if(user.getPermissions()!=null){
			 for (Permission p : user.getPermissions()) {
	                auth.addStringPermission(p.getName());
	            }
		}
		
		return auth;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken token) throws AuthenticationException {
		CaptchaUsernamePasswordToken upToken=(CaptchaUsernamePasswordToken)token;
		
		if(Strings.isBlank(upToken.getCaptcha())){
			throw new AuthenticationException("验证码不能为空");
		}
		String _captcha = Strings.sBlank(SecurityUtils.getSubject().getSession(true).getAttribute(Toolkit.captcha_attr));
		if(!upToken.getCaptcha().equalsIgnoreCase(_captcha)){
			throw new AuthenticationException("验证码错误");
		}
		
		 User user = dao().fetch(User.class, Cnd.where("name", "=", upToken.getUsername()));
	        if (user == null)
	            return null;
	        if (user.isLocked()) 
	            throw new LockedAccountException("Account [" + upToken.getUsername() + "] is locked.");
		
	    SimpleAccount account = new SimpleAccount(user.getId(),user.getPassword(),getName());
	    account.setCredentialsSalt(ByteSource.Util.bytes(user.getSalt()));
		return account;
	}
	//-----------------------------构造函数---------------------------------------
	 public NutDaoRealm() {
	        this(null, null);
	    }

	    public NutDaoRealm(CacheManager cacheManager, CredentialsMatcher matcher) {
	        super(cacheManager, matcher);
	        setAuthenticationTokenClass(CaptchaUsernamePasswordToken.class);
	    }

	    public NutDaoRealm(CacheManager cacheManager) {
	        this(cacheManager, null);
	    }

	    public NutDaoRealm(CredentialsMatcher matcher) {
	        this(null, matcher);
	    }
	  //-----------------------------构造函数---------------------------------------
	public Dao dao() {
        if (dao == null) {
            dao = Mvcs.ctx().getDefaultIoc().get(Dao.class, "dao");
            return dao;
        }
        return dao;
    }

	private void setDao(Dao dao){
		this.dao=dao;
	}
}

login.jsp页面的代码

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="${base}/js/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
	var me ='<%=session.getAttribute("me")%>';
	var base='${base}';
	$(function(){
		$("#login_button").click(function(){
			$.ajax({
				url:base+'/user/login',
				data:$("#loginForm").serialize(),
				type:"post",
				dataType:'json',
				error:function(){
					alert("connection error");
				},
				success:function(data){
					if(data&&data.ok){
						alert("登录成功");
						location.reload();
					}else{
						//alert("用户名或密码错误");
						alert(data.msg);
					}
				}
			});
			return false;
		});
		
		if(me!="null"){
			$("#login_div").hide();
			$("#userinfo").text("你的id是"+me);
			$("#user_info_div").show();
		}else{
			$("#login_div").show();
			$("#user_info_div").hide();
		}
	});

</script>
</head>

<body>
<div id="login_div">
	<form action="#" id="loginForm" method="post">
		用户名:<input name="username" type="text" value="admin"/>
		密码:<input name="password" type="password" value="123456"/>
		<script type="text/javascript">
			function next_captcha(){
				$("#captcha_img").attr("src","${base}/captcha/next?_="+new Date().getTime());
			}
		</script>
		 验证码<input name="captcha" type="text" value="">
        <img id="captcha_img" onclick="next_captcha();return false;" src="${base}/captcha/next"></img>
			<button id="login_button">登录</button>
	</form>
</div>

<div id="user_info_div">
	<p id="userinfo"></p>
	<a href="${base }/user/logout">登出</a>
</div>
</body>
</html>

nutzbook-mvc-chain.js已经加入了NutShiroProcessor

var chain={
		"default" : {
			"ps" : [
			        "net.wendal.nutzbook.mvc.LogTimeProcessor",
			        "org.nutz.mvc.impl.processor.UpdateRequestAttributesProcessor",
		            "org.nutz.mvc.impl.processor.EncodingProcessor",
		            "org.nutz.mvc.impl.processor.ModuleProcessor",
		            "org.nutz.integration.shiro.NutShiroProcessor",
		            "org.nutz.mvc.impl.processor.ActionFiltersProcessor",
		            "org.nutz.mvc.impl.processor.AdaptorProcessor",
		            "org.nutz.mvc.impl.processor.MethodInvokeProcessor",
		            "org.nutz.mvc.impl.processor.ViewProcessor"
			        ],
			"error" : 'org.nutz.mvc.impl.processor.FailProcessor'
		}
}

用的druid-1.0.16.jar包,
运行登录的时候报如下错误:

2016-10-14 09:20:48
[DEBUG]-[Thread: "http-bio-8080"-exec-4]-[org.apache.shiro.realm.AuthenticatingRealm.getAuthenticationInfo()]: Looked up AuthenticationInfo [null] from doGetAuthenticationInfo

2016-10-14 09:20:48
[DEBUG]-[Thread: "http-bio-8080"-exec-4]-[org.apache.shiro.realm.AuthenticatingRealm.getAuthenticationInfo()]: No AuthenticationInfo found for submitted AuthenticationToken [org.nutz.integration.shiro.CaptchaUsernamePasswordToken - null, rememberMe=false (0:0:0:0:0:0:0:1)].  Returning null.

调试的时候,发现upToken的username=null导致查询出来的user=null,为什么啊?????表单name是写的username呀

3 回复

使用最新shiro插件,并关联源码, debug一下 org.nutz.integration.shiro.CaptchaFormAuthenticationFilter.executeLogin(ServletRequest, ServletResponse) 方法

@wendal
我是不是进入这个坑了,网上是这样讲的:
Nutz集成Shiro的插件
简介(可用性:生产)

集成Shiro的登陆,鉴权,和Session机制
本插件的主要部件

SimpleAuthenticationFilter 穿透登陆请求到Nutz.Mvc的入口方法
SimpleShiroToken 不带校验信息的token实现
ShiroSessionProvider 在Nutz.MVC作用域内,使用Shiro替换容器原生的Session机制
ShiroProxy 用于模板引擎中方便调用shiro

原CaptchaFormAuthenticationFilter已经废弃 原因是出错了都不知道哪里错,而且不好定制.

@qq_b61182f1 debug一下能解决

添加回复
请先登陆
回到顶部