通过Shiro完成组织机构的登录、查询、退出操作

版权声明:严禁用于任何商业用途的转发!

注意:

1.这是一篇探讨性的文章,并不能作为指导性内容

2.具体的shiro认证流程等不做说明

3.在此之前,我尝试过利用shiro的ThreadLocal、数据库持久化等等手段,均没有达到理想中的效果!特别是ThreadLocal,存储后不论我怎么修改代码,一直获取不到写入的信息,有清楚原因的大大烦请指导一下!

业务需求:

1.多组织下实现用户组织认证登录

2.登录后任意请求获取当前登录组织信息

3.退出登录时,清空组织信息

实现思路:

最初的时候,我是将组织信息持久化保存到user表中,实际使用中效率以及效果并不理想,

下面代码示例中的思路是:在shiro config中初始化LoginOrgManager(自定义登录组织管理器类),在FormAuthenticationFilter中将登录组织信息写入LoginOrgManager.resources

通过Shiro完成组织机构的登录、查询、退出操作_第1张图片

实现代码:

1.自定义Token:

package org.bluedream.core.config.shiro;

import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.shiro.authc.UsernamePasswordToken;

/**
 * @ClassName CustomUserNamePasswordToken
 * @Description TODO
 * @Author foxsand
 * @Data 2021-06-18 11:25
 * @Version
 */
@Data
@NoArgsConstructor
public class CustomUsernamePasswordToken extends UsernamePasswordToken {

    private static final long serialVersionUID = 1560242330091698700L;
    private String orgCode;

    public CustomUsernamePasswordToken(String username, String password,
                                       boolean rememberMe, String host, String orgCode) {
        super(username, password, rememberMe, host);
        this.orgCode = orgCode;
    }
}

2.自定义登录表单过滤器:

package org.bluedream.core.config.shiro;

import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.bluedream.comm.utils.EmptyUtil;
import org.bluedream.core.config.shiro.loginOrganization.LoginOrgManager;
import org.bluedream.core.config.shiro.loginOrganization.LoginUserRealm;
import org.bluedream.core.utils.YmlRead;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class CustomFormAuthenticationFilter extends FormAuthenticationFilter {
    private String orgCodeParam="orgCode";
    private LoginOrgManager loginOrgManager;

    public LoginOrgManager getLoginOrgManager() {
        if (EmptyUtil.isEmpty(this.loginOrgManager)){
            this.loginOrgManager = new LoginOrgManager();
        }
        return loginOrgManager;
    }

    public void setLoginOrgManager(LoginOrgManager loginOrgManager) {
        this.loginOrgManager = loginOrgManager;
    }

    public String getOrgCodeParam() {
        return orgCodeParam;
    }
    public void setOrgCodeParam(String orgCodeParam){
        this.orgCodeParam = orgCodeParam;
    }

    protected String getOrgCode(ServletRequest request) {
        return WebUtils.getCleanParam(request, getOrgCodeParam());
    }

    @Override
    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
        String username = getUsername(request);
        String password = getPassword(request);
        String orgCode = getOrgCode(request);
        boolean rememberMe = isRememberMe(request);
        String host = getHost(request);
        return new CustomUsernamePasswordToken(username, password, rememberMe,
                host, orgCode);
    }


    /**
     * 登录成功后 将组织信息写入 LoginOrgManager.resources
     * @param token
     * @param subject
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Override
    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {
        //todo:将登陆组织信息赋值给LoginUserRealm,然后存入LoginOrgManager
        LoginOrgManager loginOrgManager = getLoginOrgManager();
        HttpServletRequest req = (HttpServletRequest) request;
        HttpSession session = req.getSession();
        CustomUsernamePasswordToken authenticationToken = (CustomUsernamePasswordToken) token;
        session.setAttribute(LoginOrgManager.LOGIN_ORG_MANAGER_KEY , authenticationToken.getOrgCode());
        session.setAttribute(LoginOrgManager.LOGIN_ORG_SUBJECT_SESSION_ID , subject.getSession().getId());

        LoginUserRealm loginUser = new LoginUserRealm(subject , authenticationToken.getOrgCode() , session);

        loginOrgManager.put((String) subject.getSession().getId() , loginUser);

        return super.onLoginSuccess(token, subject, request, response);
    }
}

3.LoginUserRealm(注意:这里我是继承了一个User类,非必要):

package org.bluedream.core.config.shiro.loginOrganization;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.apache.shiro.subject.Subject;
import org.bluedream.core.module.sys.entity.User;
import javax.servlet.http.HttpSession;


/**
 * @ClassName LoginUserRealm
 * @Description TODO
 * @Author Administrator
 * @Data 2022/5/20 16:33
 * @Version
 */
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@ToString
public class LoginUserRealm extends User {

    private static final long serialVersionUID = -5835809290701243876L;
    private Subject subject;
    private HttpSession loginOrgSession;

    public LoginUserRealm(Subject subject, String orgCode, HttpSession loginOrgSession) {
        this.subject = subject;
        setOrgCode(orgCode);
        this.loginOrgSession = loginOrgSession;
    }

    public LoginUserRealm(Subject subject) {
        this.subject = subject;
    }

    public LoginUserRealm(String orgCode) {
        this.orgCode = orgCode;
    }

    public LoginUserRealm(HttpSession loginOrgSession) {
        this.loginOrgSession = loginOrgSession;
    }

}

4.登录组织管理器:

package org.bluedream.core.config.shiro.loginOrganization;

import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName LoginOrgManager  登陆组织管理器
 * @Description TODO
 * @Author Administrator
 * @Data 2022/5/20 11:49
 * @Version
 */
@Data
@NoArgsConstructor
public class LoginOrgManager{

    private static final long serialVersionUID = -3434414553744010746L;
    public static final String LOGIN_ORG_MANAGER_KEY = LoginOrgManager.class.getName() + "_LOGIN_ORG_MANAGER_KEY";
    public static final String LOGIN_ORG_SUBJECT_SESSION_ID = LoginOrgManager.class.getName() + "_LOGIN_ORG_SUBJECT_SESSION_ID";

    private static final Map resources = new HashMap<>();

    public Map getResources() {
        return resources;
    }

    public Object getValue(String key){
        return resources != null ? resources.get(key) : null;
    }

    public Object get(String key){
        return getValue(key);
    }

    public void put(String key, Object value){
        if (key == null){
            throw new IllegalArgumentException("key cannot be null");
        }else if (value == null){
            remove(key);
        }else {
            Object obj = get(key);
            if (obj != null){
                remove(key);
            }
            resources.put(key , value);
        }
    }

    public void remove(String key){
        resources.remove(key);
    }

}

5.Logout过滤器:

package org.bluedream.core.config.shiro;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.bluedream.comm.utils.EmptyUtil;
import org.bluedream.core.config.shiro.loginOrganization.LoginOrgManager;
import org.bluedream.core.config.shiro.loginOrganization.LoginUserRealm;
import org.bluedream.core.utils.UserUtil;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;


/**
 * @ClassName CustomLogoutFilter
 * @Description TODO
 * @Author Administrator
 * @Data 2022/5/19 8:58
 * @Version
 */
public class CustomLogoutFilter extends LogoutFilter {
    private LoginOrgManager loginOrgManager;

    public LoginOrgManager getLoginOrgManager() {
        return loginOrgManager;
    }

    public void setLoginOrgManager(LoginOrgManager loginOrgManager) {
        this.loginOrgManager = loginOrgManager;
    }

    /**
     * 退出登录时,从 LoginOrgManager.resources 删除对应的组织信息
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        Subject subject = this.getSubject(request , response);
        LoginOrgManager loginOrgManager = getLoginOrgManager();
        LoginUserRealm userRealm = (LoginUserRealm) loginOrgManager.get((String) subject.getSession().getId());
        if (UserUtil.isLoginOrg(userRealm , (String) subject.getSession().getId())){
            loginOrgManager.remove((String) subject.getSession().getId());
        }

        return super.preHandle(request, response);
    }
}

6.自定义realm:

package org.bluedream.core.config.shiro;

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.bluedream.comm.utils.EmptyUtil;
import org.bluedream.core.config.exception.OrgNotPermitException;
import org.bluedream.core.config.exception.OrgNullPointException;
import org.bluedream.core.module.login.service.LoginService;
import org.bluedream.core.module.sys.entity.Menu;
import org.bluedream.core.module.sys.entity.Role;
import org.bluedream.core.module.sys.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;

public class CustomRealm extends AuthorizingRealm {
    @Autowired
    private LoginService loginService;

    @Override
    public boolean isPermitted(PrincipalCollection principals, String permission) {
        String loginCode = principals.getPrimaryPrincipal().toString();
        return loginCode.equals("system")||super.isPermitted(principals, permission);
    }

    @Override
    public boolean hasRole(PrincipalCollection principal, String roleIdentifier) {
        String loginCode = principal.getPrimaryPrincipal().toString();
        return loginCode.equals("system")||super.hasRole(principal, roleIdentifier);
    }

    /**
     * 授权信息
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        try {
            // 获取登录用户
            String loginCode = principalCollection.getPrimaryPrincipal().toString();
            User user = loginService.getLoginUser(loginCode);
            // 添加角色 、 权限 至shiro 权限管理器
            SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
            List roleList = loginService.getRoleList(user);
            List permissions = loginService.getMenuPermissions(user);

            authorizationInfo.addRoles(loginService.getRoleIds(user));

            authorizationInfo.addStringPermissions(loginService.getMenuPermissions2String(user));
            return authorizationInfo;
        }catch (Exception e1){
            e1.printStackTrace();
        }
        return null;
    }

    /**
     * 用户登录时的 身份认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        CustomUsernamePasswordToken token = (CustomUsernamePasswordToken) authenticationToken;
        String username = token.getUsername();
        String orgCode = token.getOrgCode();

        String loginCode = authenticationToken.getPrincipal().toString();
        if (EmptyUtil.isEmpty(orgCode)){
            throw new OrgNullPointException("登录组织不能为空");
        }

        //checkLoginValidityByOrg方法:验证登录用户是否拥有登录该组织的权限
        User loginUser = loginService.checkLoginValidityByOrg(loginCode , orgCode);
        if (EmptyUtil.isEmpty(loginUser)){
            throw new OrgNotPermitException("登录组织没有授权或账号信息错误");
        }

        return new SimpleAuthenticationInfo(loginCode, loginUser.getPassword(), ByteSource.Util.bytes(loginCode) , this.getClass().getName());
    }

}

7.shiro config配置类:

package org.bluedream.core.config.shiro;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.session.mgt.eis.*;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.bluedream.core.config.FilterChainDefinitionMap;
import org.bluedream.core.config.shiro.loginOrganization.LoginOrgManager;
import org.bluedream.core.utils.PasswordHelper;
import org.bluedream.core.utils.YmlRead;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import javax.servlet.Filter;
import java.util.Map;

@Configuration
public class ShiroConfig {
//    private String contextPath = (String) YmlRead.getValue("application.yml" , "server.servlet.context-path");
    /**
     * 自定义realm
     * @return
     */
    @Bean
    public CustomRealm customRealm(){
        CustomRealm realm = new CustomRealm();
        realm.setCredentialsMatcher(hashedCredentialsMatcher());
        return realm;
    }

    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(customRealm());
        securityManager.setSessionManager(sessionManager());
        // 记住我
        securityManager.setRememberMeManager(rememberMeManager());
        return securityManager;                           
    }

    /**
     * 自定义 凭证匹配器
     * @return
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        credentialsMatcher.setHashAlgorithmName(PasswordHelper.ALGORITHM_NAME);
        credentialsMatcher.setHashIterations(PasswordHelper.HASH_ITERATIONS);
        return credentialsMatcher;
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        // 装载 securityManager! 必要配置
        factoryBean.setSecurityManager(securityManager);
        // login 认证控制器
        factoryBean.setLoginUrl(YmlRead.getValueToString("application.yml", "shiro.loginUrl"));
        // login success 跳转url
        factoryBean.setSuccessUrl(YmlRead.getValueToString("application.yml", "shiro.successUrl"));
        // login no role or no Permission todo: 验证失败的处理 待测试
        factoryBean.setUnauthorizedUrl("/login");

        Map filters = factoryBean.getFilters();
        filters.put("authc" , this.authenticationFilter());
        filters.put("logout" , this.logoutFilter());

        FilterChainDefinitionMap chains = new FilterChainDefinitionMap();
        chains.setDefaultFilterChainDefinitions(YmlRead.getValueToString("application.yml", "shiro.defaultFilterChainDefinitions"));
        factoryBean.setFilterChainDefinitionMap(chains.getObject());
        return factoryBean;
    }

    private LogoutFilter logoutFilter(){
        CustomLogoutFilter logoutFilter = new CustomLogoutFilter();
        logoutFilter.setLoginOrgManager(loginOrgManager());
        logoutFilter.setRedirectUrl(YmlRead.getValueToString("application.yml", "shiro.loginUrl"));
        return logoutFilter;
    }

    private FormAuthenticationFilter authenticationFilter(){
        CustomFormAuthenticationFilter filter = new CustomFormAuthenticationFilter();
        filter.setUsernameParam("loginCode");
        filter.setOrgCodeParam("orgCode");
        filter.setRememberMeParam("rememberMe");
        filter.setLoginOrgManager(loginOrgManager());
        return filter;
    }

    /**
     * LifecycleBeanPostProcessor
     * 管理shiro一些bean的生命周期 即bean初始化 与销毁
     * @return
     */
    @Bean(name = {"lifecycleBeanPostProcessor"})
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        return new LifecycleBeanPostProcessor();
    }

    /**
     * 开启shiro注解 必要bean,依赖于lifecycleBeanPostProcessor
     * 作用: 用来扫描上下文寻找所有的Advistor(通知器), 将符合条件的Advisor应用到切入点的Bean中,需
     * 要在LifecycleBeanPostProcessor创建后才可以创建
     * @return
     */
    @Bean
    @DependsOn("lifecycleBeanPostProcessor")
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
        proxyCreator.setProxyTargetClass(true);
        return proxyCreator;
    }

    /**
     * AuthorizationAttributeSourceAdvisor
     * 作用:加入shiro注解的使用,不加入这个AOP注解不生效(shiro的注解 例如 @RequiresGuest)
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager());
        return advisor;
    }

    /**
     * session 会话管理设置
     * @return
     */
    @Bean
    public SessionManager sessionManager(){
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        // session 失效时间
        sessionManager.setGlobalSessionTimeout(1000*60*30);
        // 删除无效session
        sessionManager.setDeleteInvalidSessions(true);
/*        // 去掉URL中的JSESSIONID
        sessionManager.setSessionIdUrlRewritingEnabled(true);

        sessionManager.setSessionIdCookie(rememberMeCookie());*/
        return sessionManager;
    }

    /**
     * 记住我 设置
     * @return
     */
    @Bean
    public RememberMeManager rememberMeManager(){
        CookieRememberMeManager rememberMeManager = new CookieRememberMeManager();
        // 定义 rememberMe Cookie
        rememberMeManager.setCookie(rememberMeCookie());
        return rememberMeManager;
    }

    /**
     * 记住我 cookie设置,需要注意,开启记住我,需要user对象能够实现序列化
     * @return
     */
    @Bean
    public SimpleCookie rememberMeCookie(){
        SimpleCookie cookie = new SimpleCookie();
        // 设置cookie保存时长
        cookie.setMaxAge(30*24*60*60);
        // cookie中的名字
        cookie.setName("rememberMe");
        return cookie;
    }

    /**
     * 前端 shiro标签
     * @return
     */
    @Bean(name = "shiroDialect")
    public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }

    /**
     * 注册 shiro 监听
     * @return
     */
    @Bean(name = "sessionListener")
    public SessionListener sessionListener(){
        return new CustomShiroSessionListener();
    }

    /**
     * Session ID 生成器
     * @return
     */
    @Bean
    public SessionIdGenerator sessionIdGenerator(){
        return new JavaUuidSessionIdGenerator();
    }

    /**
     * todo 未完成
     * @return
     */
    public SessionDAO sessionDAO(){
        MemorySessionDAO sessionDAO = new MemorySessionDAO();
        return sessionDAO;
    }

    @Bean
    public LoginOrgManager loginOrgManager(){
        return new LoginOrgManager();
    }
}

User工具类:

package org.bluedream.core.utils;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.SimpleSession;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.bluedream.comm.utils.EmptyUtil;
import org.bluedream.core.config.shiro.loginOrganization.LoginOrgManager;
import org.bluedream.core.config.shiro.loginOrganization.LoginUserRealm;
import org.bluedream.core.module.login.service.LoginService;
import org.bluedream.core.module.sys.entity.Organization;
import org.bluedream.core.module.sys.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Map;


public class UserUtil {
    private static Logger logger = LoggerFactory.getLogger(UserUtil.class);

    private UserUtil(){
        throw new AssertionError();
    }


    public static String getLoginOrgCode(){
        LoginOrgManager manager = SpringUtil.getBean(LoginOrgManager.class);
        String key = (String) getSession().getId();
        LoginUserRealm realm = (LoginUserRealm) manager.get(key);

        if (isLoginOrg(realm , key)){
            return realm.getOrgCode();
        }
        return null;
    }

    /**
     * 验证 LoginUserRealm 是否正确
     * @param realm
     * @param sessionIdValidity
     * @return
     */
    public static boolean isLoginOrg(LoginUserRealm realm , String sessionIdValidity){
        /*
        1. 如果 LoginUserRealm 为空,则返回 false
        2. 验证 LoginOrgManager resources的key是否和session中的 LoginOrgManager.LOGIN_ORG_SUBJECT_SESSION_ID 是否一致
        3. 验证 LoginUserRealm 中的 orgCode是否和session中的 LoginOrgManager.LOGIN_ORG_MANAGER_KEY 是否一致
         */
        if (EmptyUtil.isEmpty(realm)){
            return false;
        }
        HttpSession session = realm.getLoginOrgSession();
        if (sessionIdValidity.equals(session.getAttribute(LoginOrgManager.LOGIN_ORG_SUBJECT_SESSION_ID))
                && realm.getOrgCode().equals(session.getAttribute(LoginOrgManager.LOGIN_ORG_MANAGER_KEY))){
            return true;
        }
        return false;
    }

    public static Session getSession(){
        try {
           Subject subject = getSubject();
           Session session = subject.getSession(false);
           if (session == null){
               return new SimpleSession();
           }
           return session;
        }catch (UnavailableSecurityManagerException var2){
        }catch (InvalidSessionException var3){
        }
        return new SimpleSession();
    }

    public static Subject getSubject() {
        return SecurityUtils.getSubject();
    }

    public static void testThreadContext(){
        LoginOrgManager manager = SpringUtil.getBean(LoginOrgManager.class);
        for (Map.Entry m1:manager.getResources().entrySet()
             ) {
            System.out.println("login org key = " + m1.getKey() + "; login org value = " + m1.getValue());
        }
    };
}

Spring工具类:

package org.bluedream.core.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if(SpringUtil.applicationContext == null) {
            SpringUtil.applicationContext = applicationContext;
        }
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static Object getBean(String name){
        return getApplicationContext().getBean(name);
    }

    public static  T getBean(Class clazz){
        return getApplicationContext().getBean(clazz);
    }

    public static  T getBean(String name , Class clazz){
        return getApplicationContext().getBean(name , clazz);
    }

}

 参考文档:Shiro基于组织机构的登录验证_sas???的博客-CSDN博客

你可能感兴趣的:(JAVA基础,spring)