Springboot+SpringMVC+Myabtis整合shiro权限控制

最近也被这个难题搞的我头都大了额。写下此篇文章献给自己和广大朋友。如果有不懂的地方可以加企鹅号询问哦。

企鹅号:2054861587,不一定会时时在,但如果有空的话就会给你回答

maven依赖:


    org.apache.shiro
    shiro-spring
    1.2.5


    org.apache.shiro
    shiro-ehcache
    1.2.5

项目下面新建Shiro配置类。

以下为配置类代码:

这里有个坑,也是这个坑让我头疼了好久,就是当你没有写自定义的ShiroRealm类时,下面代码会疯狂报错。

ps:亲,记得哦。ShiroRealm类的代码在后面。

@Configuration
public class ShiroConfiguration {
    @Bean(name = "lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean(name = "shiroRealm")
    @DependsOn("lifecycleBeanPostProcessor")
    public ShiroRealm shiroRealm() {
        ShiroRealm realm = new ShiroRealm();
        return realm;
    }

    @Bean(name = "ehCacheManager")
    @DependsOn("lifecycleBeanPostProcessor")
    public EhCacheManager ehCacheManager() {
        EhCacheManager ehCacheManager = new EhCacheManager();
        return ehCacheManager;
    }

    @Bean("securityManager")
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(shiroRealm());
        securityManager.setCacheManager(ehCacheManager());//用户授权/认证信息Cache, 采用EhCache 缓存
        return securityManager;
    }

    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager());
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        Map filterChainDefinitionManager = new LinkedHashMap<>();
        filterChainDefinitionManager.put("/logout", "logout");
        filterChainDefinitionManager.put("/user/**", "authc,roles[user]");
        filterChainDefinitionManager.put("/shop/**", "authc,roles[shop]");
        filterChainDefinitionManager.put("/admin/**", "authc,roles[admin]");
        filterChainDefinitionManager.put("/login", "anon");//anon 可以理解为不拦截
        filterChainDefinitionManager.put("/ajaxLogin", "anon");//anon 可以理解为不拦截
        filterChainDefinitionManager.put("/static/**", "anon");//静态资源不拦截
        //filterChainDefinitionManager.put("/**", "authc,roles[user]");//其他资源全部拦截
        filterChainDefinitionManager.put("/**", "anon");
        // filterChainDefinitionManager.put("/controller/MangerController", "anon");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionManager);

        shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setSuccessUrl("/");
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
        return shiroFilterFactoryBean;
    }

    @Bean
    @ConditionalOnBean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
        daap.setProxyTargetClass(true);
        return daap;
    }

    /**
     * 开启shiro aop注解支持
     * 使用代理方式,所以需要开启代码支持
     *
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
        aasa.setSecurityManager(securityManager);
        return aasa;
    }

 

ShiroRealm类:

这里的User、role、Permission为实体类,实体类代码最下面贴出,mangerService为实现层,下面也会放出代码。

public class ShiroRealm extends AuthorizingRealm {
    private Logger logger=LoggerFactory.getLogger(ShiroRealm.class);
    @Autowired
    private MangerService mangerService;


    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        logger.info("##################执行Shiro权限认证##################");
        User user= (User) principalCollection.getPrimaryPrincipal();

        if(user!=null){
            SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
            //用户的角色集合
           info.addRoles(user.getRolelist());
            //用户的权限集合
           info.addStringPermissions(user.getPerminslist());
            return info;
        }
        return null;
    }


    /**
     * 登录认证
     * @param authenticationToken
     * @return
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
       UsernamePasswordToken token= (UsernamePasswordToken) authenticationToken;
       logger.info("验证当前SubJect时获取到的token为:"+token.toString());
       User user=mangerService.getUser(token.getUsername());
        System.out.println(token.getUsername());
       if(user!=null){
            //若存在,将此用户存放到登录认证info中,无需自己做密码对比,Shiro会为我们进行密码对比校验
           List rlist = mangerService.findRoleByUid(user.getUS_ID());//获取用户角色
           List plist = mangerService.findPermissionByUid((user.getUS_ID()));//获取用户权限
           List roleStrlist=new ArrayList();////用户的角色集合
           List perminsStrlist=new ArrayList();//用户的权限集合
           for (Role role : rlist) {
               roleStrlist.add(role.getName());
           }
           for (Permission permission : plist) {
               perminsStrlist.add(permission.getName());
           }
           user.setRolelist(roleStrlist);
           user.setPerminslist(perminsStrlist);
            Session session = SecurityUtils.getSubject().getSession();
            session.setAttribute("user", user);//成功则放入session
            //若存在,将此用户存放到登录认证info中,无需自己做密码对比,Shiro会为我们进行密码对比校验
           return new SimpleAuthenticationInfo(user, user.getUS_PASS(), getName());
       }
        return null;
    }
}

 

mangerService代码如下,其余方法就不贴出了,只贴出上面ShiroRealm类调用的三个类:

public List findRoleByUid(String us_id) {
    return mdao.findRoleByUid(us_id);
}

public List findPermissionByUid(String us_id) {
    return mdao.findPermissionByUid(us_id);
}

public User getUser(String username) {
    return mdao.getUser(username);
}

mdao代码如下:

public User getUser(String username);
List findRoleByUid(String us_id);

List findPermissionByUid(String us_id);

都是最普通的代码,o(∩_∩)o 哈哈 下面上XML代码:




Controller层:
@RequestMapping(value = "/login")
public String login(HttpServletRequest request, HttpServletResponse response,Model model) {
    response.setContentType("text/html;charset=utf-8");
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(username,password);
    Subject subject=SecurityUtils.getSubject();
    try {
    logger.info("对用户["+username+"]开始进行登录验证...验证开始");
        subject.login(usernamePasswordToken);
    logger.info("对用户[" + username + "]进行登录验证..验证通过");
    } catch (UnknownAccountException e) {
        logger.info("对用户[" + username + "]进行登录验证..验证未通过,未知账户");
        logger.info("未知帐号");
    }catch (IncorrectCredentialsException ice){
        logger.info("对用户[" + username + "]进行登录验证..验证未通过,错误的凭证");
        logger.info("密码不正确");
    }catch(LockedAccountException lae){
        logger.info("对用户[" + username + "]进行登录验证..验证未通过,错误的凭证");
        logger.info("帐户已锁定");
    }catch (AuthenticationException  e){
        logger.info("用户名或密码不正确");
    }
    User user= (User) subject.getPrincipal();
     return "index";
}

博主承认上面的代码有点绕,如果实在不懂,欢迎提问,或者你直接照抄也木有问题。

表结构的兄弟不要着急,相信你们看了实体类代码后也会建表了,如果还是不明白,那就请继续往下面看,博主再说详细些。

public class User {
    private String US_ID;  //用户ID
    private String US_NAME; //用户名
    private String US_PASS;  //密码
    private List rolelist;
    private List perminslist;
以下省略N多的GET/SET/Tostring方法.
}
Role实体类:
private String id;
private String name;//角色名称
private String type;//角色类型

pemins实体类:

private String id;
private String url;//url地址
private String name;//url描述

OK后台代码搞定了。

数据库表还不知道怎么建的同学,看着博主的 实体类。String或int 为数据库的数据类型,

user表当中没有rolelist、perminslist。只有用户ID、用户名、密码

user表当中没有rolelist、perminslist。只有用户ID、用户名、密码

user表当中没有rolelist、perminslist。只有用户ID、用户名、密码

重要的事情说三遍。

还不懂?那就举个例子咯:

pemins实体类举例。

private String id;

private String url;//url地址

private String name;//url描述

那么我们在数据库当中应该这么定义:

create table pemis(

id  varchar(20),

url varchar(50),

name varchar(80)

)

那么pemins这个表我们就新建好了,有几个实体类就有几张表,亲。如果还不会,额去找你的数据库老师吧。

JSP页面调用:

<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

放在最上面,不要问为啥,我就是要励志站在顶端的男人。

 

用户已经登录显示此内容

manager角色登录显示此内容

admin角色登录显示此内容

normal角色登录显示此内容


manager or admin 角色用户登录显示此内容


-显示当前登录用户名

add权限用户显示此内容

user:query权限用户显示此内容

不具有user:query权限的用户显示此内容

OK,恭喜你成功了

 

你可能感兴趣的:(Springboot+SpringMVC+Myabtis整合shiro权限控制)