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代码结束
}

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

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

    在之前的一篇文章中,我们已经介绍了如何为一个应用添加对CAS协议的支持,进而使得我们的应用可以与所有基于CAS协议的单点登陆服务通讯.但是现在的单点登陆服务实际上并不全是通过实现CAS协议来完成的.例 ...

  2. Lind.DDD.SSO单点登陆组件的使用(原创)

    回到目录 一般sso的说明 在Lind.DDD框架里,有对单点登陆的集成,原理就是各个网站去sso网站统一登陆授权,之后在sso网站将登陆的token进行存储,存储方式随你(cache,redis,m ...

  3. cookie+memcached实现单点登陆

    10年的时候在iteye的第一篇文章记录了一下当时怎么实现我们系统的单点登陆.不过那个时候文章写的不好,思路也很浮躁,很难看懂,在csdn的第一篇技术博客打算重新温顾一下当时实现单点登陆的思路.先来看 ...

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

    场景:比如说我们要实现一个集群环境,无非是把多个项目部署到多个tomcat下,然后按照一定的算法,轮询什么的随机访问多个tomcat服务器,但是问题也会有许多,比如说,我们最开始是把登陆人的信息存放到 ...

  5. PHP单点登陆

    本文主要介绍了利用webservice,session,cookie技术,来进行通用的单点登录系统的分析与设计.具体实现语言为PHP.单点 登录,英文名为Single Sign On,简称为 SSO, ...

  6. 在多点环境下使用cas实现单点登陆及登出

    CAS 介绍 CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目.CAS 具有以下特 ...

  7. session问题总既然(深入理解)&Token问题理解&sso单点登陆理解实现

    一.Session使http协议成为有状态协议(浏览器cookie本地这个session,服务器端也有这个session) 1.ajax前端登陆无法保存session,造成无法维持登陆状态(http本 ...

  8. 单点登陆(SSO)

    一.背景 在企业发展初期,企业使用的系统很少,通常一个或者两个,每个系统都有自己的登录模块,运营人员每天用自己的账号登录,很方便.但随着企业的发展,用到的系统随之增多,运营人员在操作不同的系统时,需要 ...

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

    相信大家对单点登陆(SSO,Single Sign On)这个名词并不感到陌生吧?简单地说,单点登陆允许多个应用使用同一个登陆服务.一旦一个用户登陆了一个支持单点登陆的应用,那么在进入其它使用同一单点 ...

随机推荐

  1. MySQL-InnoDB-MVCC多版本并发控制

    一.MySQL可重复读级别下,因为MVCC引起的BUG,下图1为相应的Java代码,其中事务1的生命周期最长,循环开启的事务2.3.4...与事务1并行 ,数据的读取只会成功一次,后面的读不到新增数据 ...

  2. 【07月15日】A股滚动市盈率PE最低排名

    ​仅根据最新的市盈率计算公式进行排名,无法对未来的业绩做出预测. 方大集团(SZ000055) - 滚动市盈率PE:2.53 - 滚动市净率PB:1.13 - 滚动年化股息收益率:4.01% - 建筑 ...

  3. Qt Quick 常用元素:Textinput 与 TextEdit 文本编辑框

    一.Textinput Textinput 用于编辑一行文本,类似于 QLineEdit. font 分组属性允许你设置 Textlnput 元素所用字体的各种属性,包括字体族(family).大 小 ...

  4. PostMan测试REST接口时候,如何绕过登录的验证

    原文地址:https://blog.csdn.net/qq_34178998/article/details/80361315 之前测试的时候,需要页面进行登录之后,才能让访问后台程序,但是在进行接口 ...

  5. 解决vue刷新页面以后丢失store的数据

    刷新页面时vue实例重新加载,store就会被重置,可以把定义刷新前把store存入本地localStorage.sessionStorage.cookie中,localStorage是永久储存,重新 ...

  6. Windows环境安装PyQt5

    目录 1. 安装Python 2. 安装Pycharm 3. 安装PyQt5 4. 安装PyQt5-tools 5. 可能出现的问题 1. Qt Designer 程序位置 2. Qt Designe ...

  7. 洛谷疯狂coding~

    1.关于数学建模思想在coding之中的应用. 将马路作为一条数轴,每棵树的位置作为数轴上的坐标点,再将坐标点与数组的下标联系到一起,完成建模. 2.本题坑点在于对“其中有多少个数,恰好等于集合中另外 ...

  8. HTML+css基础 标签的起名 style标签 选择器的使用规则

    标签的起名: 1. 官方提供的标签名 2. 类名: 用class属性起的名字 3. Id名: 用id属性起的名字 唯一的 我们把这种起名叫选择器 class选择器 id选择器  标签选择器 style ...

  9. 订单1:n支付单 设计讨论

    方法一:订单1:1支付单,下单时生成1订单,并生成1支付单(这个支付单是微信需要的相关信息),设置超时时间2小时,如果订单超时,则提示用户,订单已超时,重新下单即可: 方法二:订单1:N支付单,下单时 ...

  10. python网络爬虫(1)——安装scrapy框架的常见问题及其解决方法

    Scrapy是为了爬取网站数据而编写的一款应用框架,出名,强大.所谓的框架其实就是一个集成了相应的功能且具有很强通用性的项目模板. 其实在Linux和 Mac安装,就简单的pip命令即可: pip i ...