SpringBoot权限控制

来源:互联网 发布:3d外观设计软件 编辑:程序博客网 时间:2024/06/08 03:13

权限控制是一个比较重要的知识点。
先讲一下相关理论知识,如图:
这里写图片描述
每次发送请求都会调用到controller,而controller又会调用subject,每个用户对应一个subject(subject包含了session),且subject会负责和shiro交互,securityManager管理了Realm,而Realm可以进行登录验证,可以对用户操作付权限。
通过SpringBoot做权限控制的步骤如下:
1、首先要引入相应的包。
除了要引入其他基本功能的包,还要引入和权限控制相关的包,pom代码如下:

<dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-core</artifactId>    <version>1.2.0</version></dependency><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-web</artifactId>    <version>1.2.0</version></dependency><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-ehcache</artifactId>    <version>1.2.0</version></dependency><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-spring</artifactId>    <version>1.2.0</version></dependency>

2、自定义Realm 继承自AuthorizingRealm:

package com.mySpringBoot.shiro;import java.util.ArrayList;import java.util.List;import java.util.Set;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authc.UsernamePasswordToken;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.springframework.beans.factory.annotation.Autowired;import com.mySpringBoot.bean.Module;import com.mySpringBoot.bean.Role;import com.mySpringBoot.bean.User;import com.mySpringBoot.service.UserService;/**  * @Description AuthRealm完成根据用户名去数据库的查询,并且将用户信息放入shiro中,供第二个类调用.CredentialsMatcher,完成对于密码的校验.其中用户的信息来自shiro  * @ClassName   AuthRealm  * @Date        2017年8月30日 下午9:05:03  * @Author      动脑学院-jack */public class AuthRealm extends AuthorizingRealm {    @Autowired    private UserService service;    //认证.登录    /*      *这个方法主要是做登录验证,说白了就是去数据库里面校验用户是否存在,注意这里不需要进行秘密校验,shiro会帮我们做密码校验     */    @Override    protected AuthenticationInfo doGetAuthenticationInfo(            AuthenticationToken token) throws AuthenticationException {        try {            UsernamePasswordToken utoken = (UsernamePasswordToken)token;//获取用户输入的token            String username = utoken.getUsername();            User user = service.findUserByName(username);            if (user != null) {                // 若存在,将此用户存放到登录认证info中,无需自己做密码对比,Shiro会为我们进行密码对比校验                return new SimpleAuthenticationInfo(user, user.getPassword(),                        this.getClass().getName());//放入shiro.调用CredentialsMatcher检验密码            }        }        catch (Exception e) {            e.printStackTrace();        }        return null;    }    //授权    /*      * 授权的方法是在碰到<shiro:hasPermission>标签的时候调用的,它会去检测shiro框架中的权限(这里的permissions)是否包含有该标签的name值,如果有,里面的内容显示,如果没有,里面的内容不予显示(这就完成了对于权限的认证.)     */    @Override    protected AuthorizationInfo doGetAuthorizationInfo(            PrincipalCollection principal) {        User user = (User)principal.fromRealm(this.getClass().getName())                .iterator()                .next();//获取session中的用户        List<String> permissions = new ArrayList<String>();        Set<Role> roles = user.getRoles();        if (roles.size() > 0) {            for (Role role : roles) {                Set<Module> modules = role.getModules();                if (modules.size() > 0) {                    for (Module module : modules) {                        permissions.add(module.getMname());                    }                }            }        }        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();        info.addStringPermissions(permissions);//将权限放入shiro中.        return info;    }}

3、密码校验器:

package com.mySpringBoot.shiro;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;/**  * @Description 这个类进行秘密的校验  * @ClassName   CredentialsMatcher  * @Date        2017年8月30日 下午9:17:29  * @Author      动脑学院-jack */public class CredentialsMatcher extends SimpleCredentialsMatcher {    @Override    public boolean doCredentialsMatch(AuthenticationToken token,            AuthenticationInfo info) {        UsernamePasswordToken utoken = (UsernamePasswordToken)token;        //获得用户输入的密码        String inPassword = new String(utoken.getPassword());        //获得数据库中的密码        String dbPassword = (String)info.getCredentials();        //进行密码的比对        return this.equals(inPassword, dbPassword);    }}

4、新建权限管理类:
这一步首先需要定义一个方法返回ShiroFilterFactoryBean,ShiroFilterFactoryBean对象要设置登录的URL,设置哪些路径是可以匿名访问,哪些是需要权限访问的。

@Bean(name = "shiroFilter")    public ShiroFilterFactoryBean shiroFilter(            @Qualifier("securityManager") SecurityManager manager) {        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();        bean.setSecurityManager(manager);        //配置登录的url和登录成功的url        bean.setLoginUrl("/login");        bean.setSuccessUrl("/home");        //配置访问权限        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();        filterChainDefinitionMap.put("/jsp/login.jsp*", "anon"); //表示可以匿名访问,anon表示不需要拦截        filterChainDefinitionMap.put("/loginUser", "anon");        filterChainDefinitionMap.put("/logout*", "anon");        filterChainDefinitionMap.put("/jsp/error.jsp*", "anon");        filterChainDefinitionMap.put("/jsp/index.jsp*", "authc");        filterChainDefinitionMap.put("/*", "authc");//表示需要认证才可以访问        filterChainDefinitionMap.put("/**", "authc");//表示需要认证才可以访问        filterChainDefinitionMap.put("/*.*", "authc");        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);        return bean;    }

然后配置核心安全事务管理器,返回SecurityManager对象:

//配置核心安全事务管理器    @Bean(name = "securityManager")    public SecurityManager securityManager(            @Qualifier("authRealm") AuthRealm authRealm) {        System.err.println("--------------shiro已经加载----------------");        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();        manager.setRealm(authRealm);        return manager;    }

设置密码比较器:

//配置自定义的密码比较器    @Bean(name = "credentialsMatcher")    public CredentialsMatcher credentialsMatcher() {        return new CredentialsMatcher();    }

配置自定义的权限登录器:

@Bean(name = "authRealm")    public AuthRealm authRealm(            @Qualifier("credentialsMatcher") CredentialsMatcher matcher) {        AuthRealm authRealm = new AuthRealm();        authRealm.setCredentialsMatcher(matcher);        return authRealm;    }

总体代码:

package com.mySpringBoot.shiro;import java.util.LinkedHashMap;import org.apache.shiro.mgt.SecurityManager;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.mgt.DefaultWebSecurityManager;import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class ShiroConfiguration {    @Bean(name = "shiroFilter")    public ShiroFilterFactoryBean shiroFilter(            @Qualifier("securityManager") SecurityManager manager) {        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();        bean.setSecurityManager(manager);        //配置登录的url和登录成功的url        bean.setLoginUrl("/login");        bean.setSuccessUrl("/home");        //配置访问权限        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();        filterChainDefinitionMap.put("/jsp/login.jsp*", "anon"); //表示可以匿名访问,anon表示不需要拦截        filterChainDefinitionMap.put("/loginUser", "anon");        filterChainDefinitionMap.put("/logout*", "anon");        filterChainDefinitionMap.put("/jsp/error.jsp*", "anon");        filterChainDefinitionMap.put("/jsp/index.jsp*", "authc");        filterChainDefinitionMap.put("/*", "authc");//表示需要认证才可以访问        filterChainDefinitionMap.put("/**", "authc");//表示需要认证才可以访问        filterChainDefinitionMap.put("/*.*", "authc");        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);        return bean;    }    //配置核心安全事务管理器    @Bean(name = "securityManager")    public SecurityManager securityManager(            @Qualifier("authRealm") AuthRealm authRealm) {        System.err.println("--------------shiro已经加载----------------");        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();        manager.setRealm(authRealm);        return manager;    }    //配置自定义的权限登录器    @Bean(name = "authRealm")    public AuthRealm authRealm(            @Qualifier("credentialsMatcher") CredentialsMatcher matcher) {        AuthRealm authRealm = new AuthRealm();        authRealm.setCredentialsMatcher(matcher);        return authRealm;    }    //配置自定义的密码比较器    @Bean(name = "credentialsMatcher")    public CredentialsMatcher credentialsMatcher() {        return new CredentialsMatcher();    }    @Bean    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {        return new LifecycleBeanPostProcessor();    }    @Bean    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {        DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();        creator.setProxyTargetClass(true);        //        creator.setOrder(1);        return creator;    }    @Bean    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(            @Qualifier("securityManager") SecurityManager manager) {        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();        advisor.setSecurityManager(manager);        //        advisor.setOrder(0);        return advisor;    }}
原创粉丝点击