springboot + shiro--多realm多用户表

目录

引入依赖

配置ShiroConfiguration 

自定义realm

自定义Token

自定义认证器

LoginController里

按钮权限控制

引入依赖

<!-- 引入shiro框架的依赖 -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-all</artifactId>
            <version>1.2.2</version>
        </dependency>


配置ShiroConfiguration :

@Configuration
public class ShiroConfiguration {
    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        // 设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 拦截器.权限控制map
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        // 配置不会被拦截的链接 顺序判断

        filterChainDefinitionMap.put("/login/**", "anon");
        filterChainDefinitionMap.put("/static/**", "anon");
        filterChainDefinitionMap.put("/css/**", "anon");
        filterChainDefinitionMap.put("/js/**", "anon");
        filterChainDefinitionMap.put("/img/**", "anon");
        filterChainDefinitionMap.put("/fonts/**", "anon");
        filterChainDefinitionMap.put("/layui/**", "anon");

        filterChainDefinitionMap.put("/regdologin/**", "anon");
        filterChainDefinitionMap.put("/dologin/**", "anon");

        // 配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
        filterChainDefinitionMap.put("/logout", "logout");
        // <!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
        // <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问//-->
        filterChainDefinitionMap.put("/**", "authc");
        // 默认跳转到登陆页面
        shiroFilterFactoryBean.setLoginUrl("/reglogin");
        // shiroFilterFactoryBean.setLoginUrl("/login");
        // 登陆成功后的页面
        // shiroFilterFactoryBean.setSuccessUrl("/regindex");
        // shiroFilterFactoryBean.setSuccessUrl("/index");
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    /**
     * 核心的安全事务管理器CustomModularRealmAuthenticator
     * 
     * @return
     */
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置认证器
        securityManager.setAuthenticator(customModularRealmAuthenticator());

        List<Realm> realms = new ArrayList<>();
        realms.add(myRegUserRealm());
        realms.add(myUserRealm());
        securityManager.setRealms(realms);

        return securityManager;

    }

    /**
     * 系统自带的Realm管理,主要针对多realm
     */
    @Bean
    public CustomModularRealmAuthenticator customModularRealmAuthenticator() {
        CustomModularRealmAuthenticator customModularRealmAuthenticator = new CustomModularRealmAuthenticator();
        customModularRealmAuthenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
        return customModularRealmAuthenticator;
    }

    @Bean
    public RegUserRealm myRegUserRealm() {
        RegUserRealm myRegUserRealm = new RegUserRealm();
        // myRegUserRealm.setCredentialsMatcher(hashedCredentialsMatcher());//设置解密规则
        return myRegUserRealm;
    }

    @Bean
    public SystemRealm myUserRealm() {
        SystemRealm myUserRealm = new SystemRealm();
        // myUserRealm.setCredentialsMatcher(hashedCredentialsMatcher());//设置解密规则
        return myUserRealm;
    }

  

    /**
     * 开启shiro aop注解支持. 使用代理方式;所以需要开启代码支持;否则@RequiresRoles等注解无法生效
     * 
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    /**
     * Shiro生命周期处理器
     * 
     * @return
     */
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    /**
     * 自动创建代理
     * 
     * @return
     */
    @Bean
    @DependsOn({ "lifecycleBeanPostProcessor" })
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }
}



自定义realm

public class SystemRealm extends AuthorizingRealm {
    // @Resource(name = "userServiceImp")
    @Autowired
    private UserService UserService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private RoleMenuRelMapper roleMenuRelMapper;
    @Autowired
    private MenuMapper menuMapper;

    private Logger logger = Logger.getLogger(SystemRealm.class);

    
    @Override
    public String getName() {
         return LoginType.SYSTEM;
    }
    
    /**
     * 提供用户信息,返回权限信息
     * 
     * 
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        
        logger.info("---------------------------->授权认证:");
        System.out.println("===================授权==================");
        //校验当前用户类型是否正确,正确则进入处理角色权限问题,否则跳出
        if (!principals.getRealmNames().contains(getName())) return null;
        
        Set<String> roleSet = new HashSet<>();
        Set<String> pemissionSet = new HashSet<>();

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

        User user = (User) principals.getPrimaryPrincipal();
        
        Integer roleId = user.getRoleId();
        Role role = roleService.findRoleById(roleId);

        roleSet.add(role.getRoleName());

        // 条件设置
        RoleMenuRelExample example = new RoleMenuRelExample();
        example.setOrderByClause("id desc");
        RoleMenuRelExample.Criteria criteria = example.createCriteria();

        if (roleId != null) {
            criteria.andRoleIdEqualTo(roleId);
        }
        List<RoleMenuRel> roleMenuRels = roleMenuRelMapper.selectByExample(example);

        for (RoleMenuRel roleMenuRel : roleMenuRels) {
            Integer menuId = roleMenuRel.getMenuId();
            Menu menu = menuMapper.selectByPrimaryKey(menuId);
            // String UserMenuJson = mapper.writeValueAsString(UserMenu);
            pemissionSet.add(menu.getPerms());
            System.out.println(menu.getPerms());
        }

        // 将角色名称组成的Set提供给授权info
        authorizationInfo.setRoles(roleSet);
        // 将权限名称组成的Set提供给info
        authorizationInfo.setStringPermissions(pemissionSet);
        
        authorizationInfo.addRole(LoginType.SYSTEM);
        return authorizationInfo;
    }

    /**
     * 提供帐户信息,返回认证信息
     * 
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
            throws AuthenticationException {
        logger.info("---------------------------->登陆验证:");
        CustomizedToken token = (CustomizedToken) authenticationToken;
        
        String userName = (String) authenticationToken.getPrincipal();
        String password = new String((char[]) authenticationToken.getCredentials());
        System.out.println("----------认证--------------");
        User user = UserService.findUserByUserName(userName);
        if (user == null) {
            throw new UnknownAccountException("账号或密码不正确");
        }
        // 密码错误
        if (!password.equals(user.getPassword())) {
            throw new IncorrectCredentialsException("账号或密码不正确");
        }
        // 账号锁定
        /*if (user.getState() == 0) {
            throw new LockedAccountException("账号已被锁定,请联系管理员");
        }*/
        
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
         
        return info;

    }
}


自定义Token

public class CustomizedToken extends UsernamePasswordToken {

    private static final long serialVersionUID = -8994712492402637507L;

    private String loginType;

    public CustomizedToken() {
    }

    public CustomizedToken(final String username, final String password, final String loginType) {
        super(username, password);
        this.loginType = loginType;
    }

    public String getLoginType() {
        return loginType;
    }

    public void setLoginType(String loginType) {
        this.loginType = loginType;
    }

}


自定义认证器

/**
 * Description:全局shiro拦截分发realm
 */
public class CustomModularRealmAuthenticator extends ModularRealmAuthenticator {

    @Override
    protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken)
            throws AuthenticationException {
        System.out.println("CustomModularRealmAuthenticator=========认证器测试===============");
        // 判断getRealms()是否返回为空
        assertRealmsConfigured();
        // 强制转换回自定义的MyLoginToken
        CustomizedToken token = (CustomizedToken) authenticationToken;
        // 找到当前登录人的登录类型
        String loginType = token.getLoginType();
        // 所有Realm
        Collection<Realm> realms = getRealms();
        // 找到登录类型对应的指定Realm
        Collection<Realm> typeRealms = new ArrayList<Realm>();
        for (Realm realm : realms) {
            if (realm.getName().toLowerCase().contains(loginType))
                typeRealms.add(realm);
        }

        // 判断是单Realm还是多Realm
        if (typeRealms.size() == 1)
            return doSingleRealmAuthentication(typeRealms.iterator().next(), token);
        else
            return doMultiRealmAuthentication(typeRealms, token);
    }

}


LoginController里

@Controller
public class LoginController {
    @Autowired
    private UserService userService;

    /**
     * 登录
     * 
     * @param session  HttpSession
     * @param username 用户名
     * @param password 密码
     * @return
     */
    @RequestMapping(value = "/dologin")
    @ResponseBody
    public ServerResponse login(HttpSession session, @RequestParam(required = false) String username,
            @RequestParam(required = false) String password) throws Exception {

      

        // Shiro实现登录
        // UsernamePasswordToken token = new UsernamePasswordToken(username,
        // DigestUtils.md5Hex(password.getBytes()));
        CustomizedToken token = new CustomizedToken(username, DigestUtils.md5Hex(password.getBytes()),LoginType.SYSTEM);
        Subject subject = SecurityUtils.getSubject();

        try {
            subject.login(token);
            // 把用户信息放到session里
            User user = (User) subject.getPrincipal();
            session.setAttribute("USER", user);

            return ServerResponse.createBySuccessMessage("登录成功");
        } catch (Exception e) {
            e.printStackTrace();
            return ServerResponse.createByErrorMessage("用户名或密码错误!");
        }
    }
}
 


按钮权限控制

  1. jsp页面中引入标签:<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

  2. 在要控制的按钮上:<shiro:hasPermission name="billpolicy12"><li>计费策略</li></shiro:hasPermission>,其中name的值为相应权限,对应menu表里的perms字段。加上<shiro  标签,当前用户没权限,此按钮就隐藏不显示。


表中的perms为访问对应menu的权限,对应<shiro:hasPermission name="billpolicy12">里的name的值。






猜你喜欢

转载自blog.csdn.net/zhaoyaxiansheng/article/details/86600737