shiro在登录成功后,跳转后isAuthenticated又变成false?

forai 发布于 2014/05/08 17:31
阅读 13K+
收藏 1

在jfinal中使用了shiro

用debug跟着代码查看,在DelegatingSubject(shiro的源码)的login方法里面,已经登录成功,DelegatingSubject(shiro的源码)里面的authenticated变量也是true,登录成功后,页面跳转,我的拦截器里面Subject currentUser = SecurityUtils.getSubject()拿到当前用户后,currentUser.isAuthenticated()又变成是false。

在中间我没有任何logout的操作,请问一下为什么刚刚登录成功后我的用户的认证状态又变成false了?

有没有哪位遇到过这种情况?实在找不到原因,太头疼了。

shiro经验丰富的朋友帮忙看看 - - ||

web.xml文件配置


<!-- shiro监听和拦截器 -->
	<listener>
		<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
	</listener>
	<filter>
		<filter-name>ShiroFilter</filter-name>
		<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>ShiroFilter</filter-name>
		<url-pattern>/*</url-pattern> 
	</filter-mapping>

	<!-- JFinal拦截器 -->
	<filter>
		<filter-name>jfinal</filter-name>
		<filter-class>com.jfinal.core.JFinalFilter</filter-class>
		<init-param>
			<param-name>configClass</param-name>
			<param-value>com.ang.plugin.WebConfig</param-value>
		</init-param>
	</filter>

	<filter-mapping>
		<filter-name>jfinal</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<session-config>
		<session-timeout>60</session-timeout>
	</session-config>



shiro.ini文件



[main]
#realm
myRealm = com.ang.plugin.shiro.MyShiroRealm
securityManager.realm = $myRealm

#cache
shiroCacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
shiroCacheManager.cacheManagerConfigFile = classpath:ehcache.xml
securityManager.cacheManager = $shiroCacheManager

#session
sessionDAO=org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
sessionManager=org.apache.shiro.web.session.mgt.DefaultWebSessionManager
sessionDAO.activeSessionsCacheName=shiro-activeSessionCache
sessionManager.sessionDAO=$sessionDAO
securityManager.sessionManager=$sessionManager

# 1800000 milliseconds = 30 min .default 30 min
securityManager.sessionManager.globalSessionTimeout = 1800000



ehcache.xml



<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="false"
	monitoring="autodetect" dynamicConfig="true">

	<diskStore path="java.io.tmpdir" />

	<defaultCache maxEntriesLocalHeap="10000" eternal="false"
		overflowToDisk="true" timeToIdleSeconds="20" timeToLiveSeconds="60">
	</defaultCache>

	<!-- shiro cache -->
	<cache name="myRealm.authorizationCache" maxEntriesLocalHeap="200000"
		overflowToDisk="true" eternal="false" timeToLiveSeconds="0"
		timeToIdleSeconds="0" diskPersistent="true"
		diskExpiryThreadIntervalSeconds="900">
	</cache>
	<cache name="shiro-activeSessionCache" maxEntriesLocalHeap="200000"
		overflowToDisk="true" eternal="false" timeToLiveSeconds="0"
		timeToIdleSeconds="0" diskPersistent="true"
		diskExpiryThreadIntervalSeconds="900" />

</ehcache>



MyShiroRealm类



public class MyShiroRealm extends AuthorizingRealm{

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		String loginName = (String) principals.fromRealm( 
		         getName()).iterator().next(); 
		if(StringUtils.isNotBlank(loginName)){
			String sql = "SELECT T2.ROLE_CODE FROM T_LOCALUSER T1,T_ROLE T2,T_M_LOCALUSER_ROLE T3 WHERE T1.USERID=T3.LUSERID AND T2.ROLEID=T3.ROLEID AND T1.USERNAME=?";
			// 查询用户角色信息
			List<Record> roleList=Db.find(sql,loginName);
	        if(!CollectionUtils.isEmpty(roleList)){
	        	SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
	        	Set<String> roles=new HashSet<String>();
				for (Record record : roleList) {
					roles.add(record.getStr("ROLE_CODE"));
				}
				info.setRoles(roles);
				return info;
	        }
		}
		return null;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken authcToken) throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken)authcToken;
		User user = User.dao.login(token.getUsername(), new String(token.getPassword()));
		if(user!=null){
			SecurityUtils.getSubject().getSession().setAttribute(WebConstants.CURRENT_USER_SESSION, user);
			return new SimpleAuthenticationInfo(user.getStr("USERNAME"),user.getStr("PASSWORD"), getName());
		}
		return null;
	}
	
	/**
	 * 更新用户授权信息缓存.
	 */
	public void clearCachedAuthorizationInfo(String principal) {
		SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
		clearCachedAuthorizationInfo(principals);
	}

	/**
	 * 清除所有用户授权信息缓存.
	 */
	public void clearAllCachedAuthorizationInfo() {
		Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
		if (cache != null) {
			for (Object key : cache.keys()) {
				cache.remove(key);
			}
		}
	}

}



处理登录的Controller的方法:



@LoginValidate(v = false)
	public void doLogin() {
		String fromUrl = getPara("fromUrl");
		if (!validateCaptcha(getPara("VCODE"))) {// 验证码是否正确
			keepModel(User.class);
			setAttr("error_msg", "验证码错误");
			login();
			return;
		} else {
			try {
				SecurityUtils.getSubject().login(new UsernamePasswordToken(getPara("user.USERNAME"), MD5Util.MD5(getPara("user.PASSWORD"))));
				if(StringUtils.isNotBlank(fromUrl)){
					renderTip(0,"登录成功", fromUrl);
					return;
				}else{
					renderTip(0,"登录成功", "/admin/index");
					return;
				}
			} catch (AuthenticationException e) {
				e.printStackTrace();
				setAttr("error_msg", "用户名或密码错误!");
				login();
				return;
			}
		}
	}

用户登录拦截器

public class ShiroWebLoginInvalidInterceptor implements Interceptor{

	@Override
	public void intercept(ActionInvocation ai) {
		Controller controller = ai.getController();
		if(controller instanceof BaseController){
			LoginValidate loginValidate = ai.getMethod().getAnnotation(LoginValidate.class);
			//这里不需要验证
			if(loginValidate!=null&&loginValidate.v()==false){
				ai.invoke();
				return;
			}
			Subject currentUser = SecurityUtils.getSubject();
			if(!currentUser.isAuthenticated()){//每次在这里都是认证失败,前面登录已经成功,login的时候正常
				controller.redirect("/admin" +
						"/login?fromUrl="+ai.getActionKey());
				return;
			}else{
				ai.invoke();
			}
		}else{
			ai.invoke();
		}
	}
}



Jfinal配置类
public class WebConfig extends JFinalConfig {

	/**
	 * 供Shiro插件使用。
	 */
	Routes routes;
	
	/**
	 * 配置常量
	 */
	public void configConstant(Constants me) {
		loadPropertyFile("db.properties");				// 加载少量必要配置,随后可用getProperty(...)获取值
		me.setDevMode(getPropertyToBoolean("devMode", false));
		me.setError404View("/pages/404.html");
		me.setError500View("/pages/500.html");
		//权限的界面
		me.setError403View("/pages/403.html");
		me.setError401View("/pages/401.html");
	}
	
	/**
	 * 配置路由
	 */
	public void configRoute(Routes me) {
		this.routes = me;
		//自动路由绑定 
		//默认的注册规则是截取类名Controller前的部分并首字母小写.
		AutoBindRoutes abr = new AutoBindRoutes();
//		abr.addExcludeClass(Controller.class);
		me.add(abr);
	}
	
	/**
	 * 配置插件
	 */
	public void configPlugin(Plugins me) {
		WallFilter wallFilter = new WallFilter();
		wallFilter.setDbType("oracle");
		//-------------------------------------------------------------------
		//默认的数据库连接池
		DruidPlugin druid = new DruidPlugin(getProperty("jdbc.url"),
				getProperty("jdbc.username"),
				getProperty("jdbc.password")
				  ,getProperty("jdbc.driver"));
		druid.addFilter(new StatFilter());
		druid.addFilter(wallFilter);
		//连接池最大使用连接数量 
		druid.setMaxActive(getPropertyToInt("maxActive",100));
		//连接池最小空闲
		druid.setMinIdle(getPropertyToInt("minIdle",10));
		//初始化大小 
		druid.setInitialSize(getPropertyToInt("initialSize",10));
		me.add(druid);
		
		//自动绑定table插件
		AutoTableBindPlugin  atbp = new AutoTableBindPlugin(druid,SimpleNameStyles.UP);
		atbp.setShowSql(getPropertyToBoolean("jdbc.showsql",false));
		//数据库方言
		atbp.setDialect(new OracleDialect());
		 // 配置属性名(字段名)大小写不敏感容器工厂 
		atbp.setContainerFactory( new CaseInsensitiveContainerFactory());
		me.add(atbp);
		//
		me.add(new EhCachePlugin());
		me.add(new ShiroPlugin(routes));
	}
	
	/**
	 * 配置全局拦截器
	 */
	public void configInterceptor(Interceptors me) {
		//登录状态拦截器
		me.add(new ShiroWebLoginInvalidInterceptor());
//		me.add(new SessionInViewInterceptor());//JFinal session
		//配置事物 匹配所有带save的url 也可以在方法先添加声明式事务 @Before(Tx.class)
		//me.add(new TxByRegex(".*save.*"));
		//根据方法名称配置事务
		me.add(new TxByMethodNameRegExp(".*save.*|.*del.*|.*edit.*|.*update.*", false));
		//Shiro拦截器
		me.add(new ShiroInterceptor());
	}
	
	/**
	 * 配置处理器
	 */
	public void configHandler(Handlers me) {
//		me.add(new SessionHandler());//将session里的参数传递到request中直接得到
		me.add(new BasePathHandler("root"));
		//图片路径
		String carLogoHttp = ConfigUtil.getStr("CARLOGO_IMG_HTTP");
		me.add(new KeyValueHandler("CARLOGO_IMG_HTTP",carLogoHttp));
		me.add(new ThemePathHandler("theme","blue"));
	}
	
}






加载中
0
玛雅牛
玛雅牛

把你的相关代码贴出来,给的信息太少了。

0
forai
forai

引用来自“玛雅牛”的评论

把你的相关代码贴出来,给的信息太少了。

牛哥,已经贴上了所有相关代码,跪求指导。实在是头疼了。
0
q
quinnhe
楼主解决了,求分享解决方法
0
forai
forai

引用来自“quinnhe”的评论

楼主解决了,求分享解决方法

这个问题有点奇怪,后面就好了。

你参考一下这里,有可能是session丢失的原因:http://blog.csdn.net/wkq_361138880/article/details/20718089

返回顶部
顶部