NutzCN Logo
问答 shiro实现多个系统登录验证
发布于 2174天前 作者 xiaoqiu1235 4076 次浏览 复制 上一个帖子 下一个帖子
标签:

我现在在用户系统中使用nutz的集成的shiro进行登录验证后保存到redis和本地缓存中。
现在有另外一个支付系统(springboot)也需要验证用户是否登录,请问这个怎么读取redis中用户登录信息判断是否登录呢

7 回复

开个api让它调用

能不能详细点,搞个伪代码,我没有一点头绪。

做个入口方法供它查询是否登录, 而不是去操作redis

我在realm中的验证是这样的

@Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String username = token.getUsername();
        String password = String.valueOf(token.getPassword());

        ServiceResult sr = ServiceManager.tranService(getAuthService(), "doLogin", username, password);
        if (!sr.result) {
            throw new AuthenticationException(sr.message);
        }

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password, this.getName());
        return info;
    }

但是我通过Subject获取用户的登录信息是渠道当天session登录的信息,支付系统中调用接口传一个用户ID过来,要怎么判断是否登录呢
这是判断登录的接口代码

@At(value = "/isLogin", methods = {"POST"})
    public void login(HttpServletResponse response, @Param("chUserId") Integer mid) {
        try {
            Subject subject = SecurityUtils.getSubject();
            PrintWriter writer = response.getWriter();
            Auth auth = (Auth) subject.getSession().getAttribute(Auth.AUTH_KEY);
            if (auth == null) {
                writer.write("ERROR");
            }
            if (auth.getId() == mid) {
                System.out.println(subject.getPrincipal());
                System.out.println(subject.isAuthenticated());
                writer.write("SUCCESS");
            }
            writer.write("ERROR");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

登录的时候,把session id存到用户表/其他地方。根据session id可以构建出shiro session的

目前是用redis存储了session信息,看到redis中用户登录后存了一个cookie sid和用户名

DXJ50: 2018-12-10 14:33:13,669 [http-bio-8080-exec-48] DEBUG org.apache.shiro.web.servlet.SimpleCookie - Found 'sid' cookie value [v48673f9voj0cpeueroqilaiia]

redis中存了

shiro-activeSessionCache:v48673f9voj0cpeueroqilaiia
shiro-activeSessionCache:18673196119

但是

shiro-activeSessionCache:v48673f9voj0cpeueroqilaiia

shiro-activeSessionCache:18673196119

时间要长些,请问怎么设置这两个时间一直呢
这是shiro.ini配置

[main]

#Session管理器,关闭定时校验机制,持久化环境下会非常耗内存
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
sessionManager.sessionValidationSchedulerEnabled = false
sessionManager.sessionIdUrlRewritingEnabled = false
sessionManager.deleteInvalidSessions = true

#带缓存的SessionDAO
sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
sessionManager.sessionDAO = $sessionDAO
securityManager.sessionManager = $sessionManager

# use R.UU32(), 原生的是UUID,比较长
sessionIdGenerator = org.nutz.integration.shiro.UU32SessionIdGenerator
securityManager.sessionManager.sessionDAO.sessionIdGenerator = $sessionIdGenerator

#记住我
rememberMeCookie = org.apache.shiro.web.servlet.SimpleCookie
rememberMeCookie.name=remember
rememberMeCookie.maxAge = 604800
rememberMeCookie.httpOnly = true
rememberMeManager = org.apache.shiro.web.mgt.CookieRememberMeManager
rememberMeManager.cookie = $rememberMeCookie

# 2层缓存配置
jedisAgent = org.nutz.integration.jedis.JedisAgent
cacheManager_ehcache = org.apache.shiro.cache.ehcache.EhCacheManager
cacheManager_ehcache.cacheManagerConfigFile=classpath:ehcache.xml
cacheManager_redis = org.nutz.plugins.cache.impl.redis.RedisCacheManager
cacheManager_redis.mode=kv
cacheManager_redis.debug=true
cacheManager_redis.ttl=1800
cacheManager = org.nutz.plugins.cache.impl.lcache.LCacheManager
cacheManager.level1 = $cacheManager_ehcache
cacheManager.level2 = $cacheManager_redis
cacheManager.jedisAgent = $jedisAgent
securityManager.sessionManager.cacheManager = $cacheManager
#securityManager.rememberMeManager = $rememberMeManager

# realm声明
nutzdao_realm = com.hxd.shiro.realm.UserRealm

# cookie, nutzcn使用超长时间的cookie,所以下面的timeout都很长
sessionIdCookie=org.apache.shiro.web.servlet.SimpleCookie
sessionIdCookie.name=sid
sessionIdCookie.maxAge=1800000
sessionIdCookie.httpOnly=true
sessionManager.sessionIdCookie=$sessionIdCookie
sessionManager.sessionIdCookieEnabled=true
sessionManager.globalSessionTimeout=1800000

kickout=com.hxd.shiro.filter.KickoutSessionControlFilter
kickout.cacheManager=$cacheManager
kickout.sessionManager=$sessionManager
kickout.kickoutUrl=/login

authc = org.nutz.integration.shiro.SimpleAuthenticationFilter
authc.loginUrl  = /login
perms.loginUrl  = /login
roles.loginUrl  = /login
user.loginUrl   = /login
rest.loginUrl   = /login
logout.redirectUrl= /login


[urls]
/static/*        = anon, noSessionCreation
/druid/*        = anon, noSessionCreation
/style/*        = anon, noSessionCreation
/swagger/**        = anon, noSessionCreation

/member/V1.0/fuiouWebReg = authc,kickout
/member/V1.0/fuiouChangeBandCard = authc,kickout
/member/V1.0/fuiouMobileChange = authc,kickout
/member/V1.0/fuiouPassWordChange = authc,kickout
/member/V1.0/fuiouQuickRecharge = authc,kickout
/member/V1.0/fuiouWithdraw = authc,kickout
/member/V1.0/* = anon

/wx/member/V1.0/fuiouWebReg = authc,kickout
/wx/member/V1.0/fuiouChangeBandCard = authc,kickout
/wx/member/V1.0/fuiouMobileChange = authc,kickout
/wx/member/V1.0/fuiouPassWordChange = authc,kickout
/wx/member/V1.0/fuiouQuickRecharge = authc,kickout
/wx/member/V1.0/fuiouWithdraw = authc,kickout
/wx/member/V1.0/* = anon

/member/** = authc,kickout


/wx/member/** = authc,kickout


/member/logout = logout
/wx/member/logout = logout

请问不存储到数据中,怎么在redis的存储中拿到信息判断用户是否登录呢

目前解决了,通过这种方式可以判断

@At(value = "/isLogin", methods = {"POST"})
    @Filters({@By(type = XssAnoFilter.class),@By(type = IpFilter.class)})
    public void login(HttpServletResponse response, @Param("chUserId") String userName) {
        try {
            DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
            DefaultWebSessionManager sessionManager = (DefaultWebSessionManager) securityManager.getSessionManager();
            EnterpriseCacheSessionDAO sessionDAO = (EnterpriseCacheSessionDAO) sessionManager.getSessionDAO();
            CacheManager cacheManager = sessionDAO.getCacheManager();
            Cache<String, Deque<Serializable>> cache = cacheManager.getCache("shiro-activeSessionCache");
            Deque<Serializable> serializables = cache.get(userName);
            PrintWriter writer = response.getWriter();
            if (serializables == null) {
                writer.write("SUCCESS");
            } else {
                writer.write("ERROR");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
添加回复
请先登陆
回到顶部