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">--> <!--<!– 配置认证策略,只要有一个Realm认证成功即可,并且返回所有认证成功信息 –>--> <!--<property name="authenticationStrategy">--> <!--<bean class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"></bean>--> <!--</property>--> <!--</bean>--> <!--<bean id="frontSecurityService" class="im.lsn.oss.exhibition.service.FrontSecurityService">--> <!--<!– 配置密码匹配器 –>--> <!--<property name="credentialsMatcher">--> <!--<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">--> <!--<!– 加密算法为MD5 –>--> <!--<property name="hashAlgorithmName" value="MD5"></property>--> <!--<!– 加密次数 –>--> <!--<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