• 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代码结束
    }
  • 相关阅读:
    windows7触屏编程
    改变窗口大小,恢复以前的大小
    insert()
    index()
    help()
    id()
    extend()
    count()
    cmp()
    append()
  • 原文地址:https://www.cnblogs.com/ly-lyq/p/9987433.html
Copyright © 2020-2023  润新知