sessionId控制单点登陆

1.配置security-context.xml文件


<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"       default-lazy-init="true">

<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">        <constructor-arg value="rememberMe"/>        <property name="httpOnly" value="true"/>        <property name="maxAge" value="2592000"/><!-- 30天 -->    </bean>

<!-- rememberMe管理器 -->    <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">        <!-- rememberMe cookie加密的密钥 每个项目都不一样 默认AES算法 用下面的代码产生不同的密码        AesCipherService aes = new AesCipherService();     byte[] key = aes.generateNewKey().getEncoded();     String base64 = Base64.encodeToString(key);        -->        <property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode(‘kbFQXD6nkE8QuvzqlV9UYA==‘)}"/>        <property name="cookie" ref="rememberMeCookie"/>    </bean>

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">        <property name="realm" ref="securityService"/>        <!-- 可以配置多个Realm,其实会把realms属性赋值给ModularRealmAuthenticator的realms属性 -->        <!--<property name="realms">-->        <!--<list>-->        <!--<ref bean="securityService" />-->        <!--<ref bean="frontSecurityService"/>-->        <!--</list>-->        <!--</property>-->        <property name="rememberMeManager" ref="rememberMeManager"/>        <property name="sessionManager" ref="sessionManager"/><!--单点登陆的配置代码开始-->        <property name="authenticator.authenticationListeners">            <list>                <ref bean="securityService"/>            </list>        </property><!--单点登陆代码结束-->    </bean>

<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">        <property name="sessionValidationInterval" value="60000"/>        <property name="globalSessionTimeout" value="300000"/>    </bean>

<!-- 配置使用自定义认证器,可以实现多Realm认证,并且可以指定特定Realm处理特定类型的验证 -->    <!--<bean id="authenticator" class="im.lsn.oss.exhibition.shiro.CustomizedModularRealmAuthenticator">-->    <!--&lt;!&ndash; 配置认证策略,只要有一个Realm认证成功即可,并且返回所有认证成功信息 &ndash;&gt;-->    <!--<property name="authenticationStrategy">-->    <!--<bean class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"></bean>-->    <!--</property>-->    <!--</bean>-->

<!--<bean id="frontSecurityService" class="im.lsn.oss.exhibition.service.FrontSecurityService">-->    <!--&lt;!&ndash; 配置密码匹配器 &ndash;&gt;-->    <!--<property name="credentialsMatcher">-->    <!--<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">-->    <!--&lt;!&ndash; 加密算法为MD5 &ndash;&gt;-->    <!--<property name="hashAlgorithmName" value="MD5"></property>-->    <!--&lt;!&ndash; 加密次数 &ndash;&gt;-->    <!--<property name="hashIterations" value="1024"></property>-->    <!--</bean>-->    <!--</property>-->    <!--</bean>-->

<bean id="formAuthenticationTenantFilter" class="im.lsn.oss.exhibition.web.admin.Security.AdminFilter"/>    <bean id="frontFilter" class="im.lsn.oss.exhibition.web.front.Security.FrontFilter"/>    <bean id="authShiroFilter" class="im.lsn.oss.exhibition.web.filter.AuthShiroFilter"/>    <bean id="logout" class="im.lsn.oss.exhibition.web.MyLogoutFilter">        <property name="redirectUrl" value="/jsp/login.jsp"/>        <property name="frontRedirectUrl" value="/front/index.do"/>    </bean>    <bean id="shiroSecurityFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">        <property name="securityManager" ref="securityManager"/>        <property name="loginUrl" value="/jsp/login.jsp"/>        <property name="successUrl" value="/jsp/login_success.jsp"/>        <property name="filters">            <map>                <entry key="authc" value-ref="formAuthenticationTenantFilter"/>                <entry key="rolesor" value-ref="authShiroFilter"/>                <entry key="logout" value-ref="logout"/>                <entry key="front" value-ref="frontFilter"/>            </map>        </property>        <property name="filterChainDefinitions">            <value>                /jsp/login.jsp = authc                /logout = logout                <!--/f/logout = logout-->                <!--/jsp/front/user_login.jsp = front-->                <!--/front/visitor/user/*= front-->                <!--/front/visitor/user_favorites.do=front-->                /admin/index.do = rolesor[admin,operator_admin,venue_admin,organizer_admin,exhibitors_admin]                /admin/organizer/exhibitorInfoListing.do = rolesor[admin,operator_admin,venue_admin,organizer_admin]                /admin/organizer/exhibitorInfoList.do = rolesor[admin,operator_admin,venue_admin,organizer_admin]                /admin/organizer/verify.do = rolesor[admin,operator_admin,venue_admin,organizer_admin]                /admin/organizer/save_verify.do = rolesor[admin,operator_admin,venue_admin]                /admin/organizer/exhibitor_info_index.do = rolesor[admin,operator_admin,venue_admin,organizer_admin]                /admin/organizer/fail_exhibitorInfoList.do = rolesor[admin,operator_admin,venue_admin,organizer_admin]                /admin/organizer/hotRecommend.do = rolesor[admin,operator_admin,venue_admin]                /admin/organizer/identifierList.do = rolesor[admin,operator_admin,venue_admin,organizer_admin]                /admin/exhibitors/wait_index.do = rolesor[admin,operator_admin,organizer_admin,exhibitors_admin]                /admin/exhibitors/booth_index.do = rolesor[admin,operator_admin,organizer_admin,exhibitors_admin]                /admin/exhibitors/fail_index.do = rolesor[admin,operator_admin,organizer_admin,exhibitors_admin]                /admin/exhibitors/booth_preview.do = rolesor[admin,operator_admin,organizer_admin,exhibitors_admin]                /admin/exhibitors/mark.do = rolesor[admin,operator_admin,organizer_admin,exhibitors_admin]                /admin/exhibitors/save_mark.do = rolesor[admin,operator_admin,organizer_admin]                /admin/exhibitors/edit_booth_venue_branch.do = rolesor[admin,operator_admin,organizer_admin,exhibitors_admin]                /admin/exhibitors/wait_product.do = rolesor[admin,operator_admin,organizer_admin,exhibitors_admin]                /admin/exhibitors/product_index.do = rolesor[admin,operator_admin,organizer_admin,exhibitors_admin]                /admin/exhibitors/fail_product.do = rolesor[admin,operator_admin,organizer_admin,exhibitors_admin]                /admin/exhibitors/product_preview.do = rolesor[admin,operator_admin,organizer_admin,exhibitors_admin]                /admin/exhibitors/ProductHotRecommend.do = rolesor[admin,operator_admin,organizer_admin]                /admin/information/** = rolesor[admin,operator_admin]                /admin/log/** = rolesor[admin,operator_admin]                /admin/user/** = rolesor[admin,operator_admin,venue_admin,organizer_admin,exhibitors_admin]                /admin/user/index.do = rolesor[admin,operator_admin]                /admin/venue/** = rolesor[admin,operator_admin,venue_admin]                /admin/organizer/** = rolesor[admin,venue_admin,organizer_admin]                /admin/exhibitors/** = rolesor[admin,organizer_admin,exhibitors_admin]                /admin/venue/index.do = rolesor[admin,operator_admin]                /admin/organizer/index.do = rolesor[admin,venue_admin]                /admin/operator/edit.do = rolesor[admin,operator_admin]                /admin/** = rolesor[admin]            </value>        </property>    </bean></beans>
 

2.security

import im.lsn.framework.BusinessLogicException;
import im.lsn.framework.jpa.JpaRepositoryImpl;
import im.lsn.framework.shrio.CustomSecurityException;
import im.lsn.oss.exhibition.entity.*;
import im.lsn.oss.exhibition.entity.enumerate.LoginType;
import im.lsn.oss.exhibition.entity.enumerate.VistorType;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.DigestUtils;

import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.Collection;
import java.util.Date;

/**
 * Created by fireflyc on 2017/4/26.
 */
@Service
@Transactional
public class SecurityService extends AuthorizingRealm implements AuthenticationListener{
    private Logger LOGGER = LoggerFactory.getLogger(SecurityService.class);

    @Autowired
    UserService userService;
    @Autowired
    private ClickedCountService clickedCountService;

    @Autowired
    private DefaultSessionManager sessionManager;

    @PersistenceContext
    protected EntityManager entityManager;
    private JpaRepositoryImpl<TbUser, Long> userRepository;
    private JpaRepositoryImpl<TbRole, Long> roleRepository;
    private JpaRepositoryImpl<TbUserState, Long> userStateLongJpaRepository;
    private JpaRepositoryImpl<TbType, Long> typeLongJpaRepository;
    private JpaRepositoryImpl<TbExhibitionUser, Long> exhibitionUserLongJpaRepository;

    @PostConstruct
    public void initSecurityService() {
        this.userRepository = new JpaRepositoryImpl<TbUser, Long>(TbUser.class, entityManager);
        this.roleRepository = new JpaRepositoryImpl<TbRole, Long>(TbRole.class, entityManager);
        this.userStateLongJpaRepository = new JpaRepositoryImpl<TbUserState, Long>(TbUserState.class, entityManager);
        this.exhibitionUserLongJpaRepository = new JpaRepositoryImpl<TbExhibitionUser, Long>(TbExhibitionUser.class, entityManager);

        this.typeLongJpaRepository = new JpaRepositoryImpl<TbType, Long>(TbType.class, entityManager);
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher("MD5");
        setCredentialsMatcher(matcher);
    }

    @EventListener
    public void createAdminAccount(ContextRefreshedEvent event) {
        TbRole role = roleRepository.findOne(QTbRole.tbRole.id.eq(1L));
        if (role == null) {
            role = new TbRole();
            role.setRoleName("系统管理员");
            role.setRoleCnName("admin");
            roleRepository.save(role);
            LOGGER.info("创建系统管理员角色");
        }

        TbUser user = userRepository.findOne(QTbUser.tbUser.id.eq(1L));
        TbUserState userState = userStateLongJpaRepository.findOne(1L);
        TbType type = typeLongJpaRepository.findOne(1L);
        if (user == null) {
            user = new TbUser();
            user.setId(1L);
            user.setCreateTime(new Date());
            user.setRole(role);
            user.setUsername("admin_tontron");
            user.setNickname("系统管理员");
            String password = "admin_tontron" + DigestUtils.md5DigestAsHex("Tontron1169".getBytes());
            user.setPassword(password);
            user.setState(userState);
            user.setType(type);
            userRepository.save(user);
            LOGGER.info("创建系统管理员");
        }
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        UserLoginToken userToken = (UserLoginToken) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        if (userToken.getType().equals(LoginType.ADMIN.toString())) {
            authorizationInfo.addRole(userToken.getRole().getRoleName());
        } else {
            authorizationInfo.addRole(userToken.getFrontRole());
        }
        return authorizationInfo;
    }

    public void logout() {
        SecurityUtils.getSubject().logout();
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
        if (authcToken instanceof UsernamePasswordToken) {
            CustomizedToken token = (CustomizedToken) authcToken;
            if (token.getLoginType().equals(LoginType.ADMIN.toString())) {
                try {
                    QTbUser qUser = QTbUser.tbUser;
                    TbUser user = userRepository.findOne(qUser.username.eq(token.getUsername()));
                    TbUserState userState = userStateLongJpaRepository.findOne(2L);
                    if (user == null) {
                        throw new UnknownAccountException();
                    }
                    if (user.getState().getStateName().equals(userState.getStateName())) {
                        throw new BusinessLogicException("账号被禁用,无法登录");
                    }
                    if(null != user.getClickedCount() && 5<user.getClickedCount()){
                        Integer count = user.getClickedCount();
                        count++;
                        clickedCountService.updateClickedCount(user.getId(),count);
                        throw new BusinessLogicException("登陆失败次数过多,请明天再尝试");
                    }
                    LOGGER.info("用户{} 存在", user.getNickname());
                    String showName = user.getNickname();
                    if (null == showName || showName.length() == 0) {
                        showName = userService.searchShowNameForUser(user);
                    }
                    UserLoginToken loginToken = new UserLoginToken();
                    loginToken.setUserId(user.getId());
                    loginToken.setUserName(user.getUsername());
                    loginToken.setNickName(user.getNickname());
                    loginToken.setRole(user.getRole());
                    loginToken.setShowName(showName);
                    loginToken.setType(token.getLoginType());
                    loginToken.setSubUser(user.getSubUser());
                    return new SimpleAuthenticationInfo(loginToken,
                            user.getPassword(), getName());
                } catch (BusinessLogicException e) {
                    throw new CustomSecurityException(e.getMessage());
                } catch (Exception e) {
                    LOGGER.error(e.getMessage(), e);
                    if (e instanceof UnknownAccountException) {
                        throw new UnknownAccountException();
                    } else {
                        throw new CustomSecurityException("用户名或密码错误");
                    }

                }
            } else {
                try {
                    QTbExhibitionUser qTbExhibitionUser = QTbExhibitionUser.tbExhibitionUser;
                    TbExhibitionUser exhibitionUser = exhibitionUserLongJpaRepository.findOne(qTbExhibitionUser.phone.eq(token.getUsername()));

                    if (exhibitionUser == null) {
                        throw new UnknownAccountException();
                    }
                    LOGGER.info("用户{} 存在", exhibitionUser.getPhone());
                    UserLoginToken loginToken = new UserLoginToken();
                    loginToken.setUserId(exhibitionUser.getId());
                    loginToken.setUserName(exhibitionUser.getPhone());
                    loginToken.setFrontRole(VistorType.EXHIBITOR_USER.getName());
                    loginToken.setShowName(exhibitionUser.getPhone());
                    loginToken.setType(token.getLoginType());
                    return new SimpleAuthenticationInfo(loginToken,
                            exhibitionUser.getPassword(), getName());
                } catch (BusinessLogicException e) {
                    throw new CustomSecurityException(e.getMessage());
                } catch (Exception e) {
                    LOGGER.error(e.getMessage(), e);
                    throw new CustomSecurityException("用户名或密码错误");
                }

            }

        }
        return null;
    }

    public UserLoginToken getLoginToken() {
        try {
            Subject subject = SecurityUtils.getSubject();
            if (subject == null) {
                return null;
            }
            return (UserLoginToken) subject.getPrincipal();
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            return null;
        }
    }

    public TbUser getLoginUser() {
        UserLoginToken loginToken = getLoginToken();
        Assert.notNull(loginToken);
        TbUser tbUser = userRepository.selectFrom(QTbUser.tbUser)
                .where(QTbUser.tbUser.id.eq(loginToken.getUserId())).fetchOne();
        return tbUser;
    }

    public TbExhibitionUser getFrontLoginUser() {
        UserLoginToken loginToken = getLoginToken();
        Assert.notNull(loginToken);
        TbExhibitionUser exhibitionUser = exhibitionUserLongJpaRepository.selectFrom(QTbExhibitionUser.tbExhibitionUser)
                .where(QTbExhibitionUser.tbExhibitionUser.id.eq(loginToken.getUserId())).fetchOne();
        return exhibitionUser;
    }

//单点登陆的java代码
    public void onSuccess(AuthenticationToken token, AuthenticationInfo info){
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken loginToken = (UsernamePasswordToken) token;
        Collection<Session> sessions = sessionManager.getSessionDAO().getActiveSessions();
        for (Session session : sessions) {
            Subject sub = new Subject.Builder().session(session).buildSubject();
            if (sub.isAuthenticated()) {
                UserLoginToken other = (UserLoginToken) sub.getPrincipal();
                if (other.getUserName().equals(loginToken.getUsername())) {
                    if (!session.getId().equals(subject.getSession().getId())) {
                        session.stop();
                    }
                }
            }
        }
    }

    public void onFailure(AuthenticationToken var1, AuthenticationException var2){

    }

    public void onLogout(PrincipalCollection var1){

    }
//单点登陆的java代码结束
}

原文地址:https://www.cnblogs.com/ly-lyq/p/9987433.html

时间: 2024-11-08 23:39:00

sessionId控制单点登陆的相关文章

集成基于OAuth协议的单点登陆

在之前的一篇文章中,我们已经介绍了如何为一个应用添加对CAS协议的支持,进而使得我们的应用可以与所有基于CAS协议的单点登陆服务通讯.但是现在的单点登陆服务实际上并不全是通过实现CAS协议来完成的.例如Google就使用OAuth协议来管理它的帐户. 相较于CAS协议,OAuth协议不仅仅可以完成对用户凭证的验证,更可以提供权限管理的功能.在这些权限管理功能的支持下,一个应用甚至可以访问其它使用相同OAuth服务的应用的数据,从而完成应用间的交互. OAuth集成示例 现在我们就来看一个通过OA

WebLogic Server的单点登陆功能--转载

在WebLogic 8.1最新的 SP4版本中,最引人注目的要算是在安全方面,提供了用于和Microsoft Windows客户端进行Single Sign-On的Single Pass Negotiate Identity Assertion Provider.通过该Provider可以轻松完成从前认为技术难度很高的和Windows客户端的Single Sign-On. 这个简单,低成本的SSO解决方案相信对大多数的企业应用来说更具吸引力: 用户只需要开机时登录Windows域,就可以以登录用

cookie+memcached实现单点登陆

10年的时候在iteye的第一篇文章记录了一下当时怎么实现我们系统的单点登陆.不过那个时候文章写的不好,思路也很浮躁,很难看懂,在csdn的第一篇技术博客打算重新温顾一下当时实现单点登陆的思路.先来看看什么叫单点登陆 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.它包括可以将这次主要的登录映射到其他应用中用于同一个用户的登录的机制. --百度百科 为什么要实

php 用CAS实现SSO单点登陆及登出功能

php用CAS实现SSO单点登陆及登出功能 一..CAS服务器搭建 CAS服务器端下载地址:http://downloads.jasig.org/cas/ 解压cas-server-4.0.0-release.zip将modules目录下的cas-server-webapp-4.0.0.war改名称为cas.war复制到tomcat的webapps下,启动tomcat,访问:http://localhost:8080/cas/login 就可以看到登录界面了: cas服务端默认采用的是 用户名=

在tomcat集群下利用redis实现单点登陆

场景:比如说我们要实现一个集群环境,无非是把多个项目部署到多个tomcat下,然后按照一定的算法,轮询什么的随机访问多个tomcat服务器,但是问题也会有许多,比如说,我们最开始是把登陆人的信息存放到session中,但是如果是集群的情况下,比如我第一次登陆,把信息存放到session里面,但是我第二次访问的时候,访问到了第二台服务器,第二台服务器里面没有session信息,我们还得再登陆一遍,问题显而易见,session数据共享的问题. 解决思路:我们不要把信息存放到服务器的session中,

单点登陆的测试

今天做了个单点登陆 . 但是怎么测试呢? 下面请看详解: 源码中是这样的: /** * 单点登录改造 * * @param request * @param response * @return * @throws IOException * @throws HttpException * @throws IOException */ @RequestMapping(value = "/rcbSingleLoginCheck.do") public Object singleLogin

ASP.NET在不同情况下实现单点登陆(SSO)的方法

第一种:同主域但不同子域之间实现单点登陆 Form验证其实是基于身份cookie的验证.客户登陆后,生成一个包含用户身份信息(包含一个ticket)的cookie,这个cookie的名字就是在web.config里Authentication节form设定的name信息,如 <authentication mode="Forms"> <forms loginUrl="login.aspx" name=".ASPXAUTH" pa

单点登陆sso实现

需求: 多个bs业务系统,在某个业务系统登陆后,访问其他bs应用系统无需重复登陆. 制约:必须同一浏览器. 解决方案: 关键词:cookie,跨域,sso 环境 l Passport.com 登陆认证服务 l pis.com 病理业务系统 l lis.com 检验业务系统 l  login 拦截器:验证请求是否有令牌,令牌是否合法() l  令牌 ticket 括号内为增强功能 l  用户访问pis.com,拦截器发现无令牌或令牌无效,跳转至passport.com的登陆页面(防止恶意测试密码,

集成基于CAS协议的单点登陆

相信大家对单点登陆(SSO,Single Sign On)这个名词并不感到陌生吧?简单地说,单点登陆允许多个应用使用同一个登陆服务.一旦一个用户登陆了一个支持单点登陆的应用,那么在进入其它使用同一单点登陆服务的应用时就不再需要重新登陆了.而CAS协议则正是各单点登陆产品所需要实现的协议,其全称为Central Authentication Service. 那为什么要写这篇博客呢?这是因为在为公司的产品集成SSO的时候,我发现如果软件开发人员不了解CAS协议,那么他在集成出现错误的时候将完全没有