博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringBoot权限控制
阅读量:6617 次
发布时间:2019-06-25

本文共 9804 字,大约阅读时间需要 32 分钟。

权限控制是一个比较重要的知识点。

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

org.apache.shiro
shiro-core
1.2.0
org.apache.shiro
shiro-web
1.2.0
org.apache.shiro
shiro-ehcache
1.2.0
org.apache.shiro
shiro-spring
1.2.0

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框架中的权限(这里的permissions)是否包含有该标签的name值,如果有,里面的内容显示,如果没有,里面的内容不予显示(这就完成了对于权限的认证.) */ @Override protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principal) { User user = (User)principal.fromRealm(this.getClass().getName()) .iterator() .next();//获取session中的用户 List
permissions = new ArrayList
(); Set
roles = user.getRoles(); if (roles.size() > 0) { for (Role role : roles) { Set
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
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
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; }}

转载地址:http://hbypo.baihongyu.com/

你可能感兴趣的文章
海量小文件同步
查看>>
Hyper-V 2016 系列教程58 用SCVMM 2016 新建虚拟机 VM
查看>>
mysql严重查询速度的问题一则
查看>>
Windows系统中基于策略的桌面管理
查看>>
根据一位博友用(MDT+WDS部署windows xp)
查看>>
pureftp 适合企业用啊
查看>>
Red Hat Enterprise Linux6 自动挂载Windows文件系统
查看>>
FCKeditor无test上传页面二次上传
查看>>
分形树Fractal tree介绍——具体如何结合TokuDB还没有太懂,先记住其和LSM都是一样的适合写密集...
查看>>
让pt-slave-restart支持MariaDB
查看>>
Android系统应用可靠性测试-猴子测试与Monkey应用实战
查看>>
灵活运用ISA的链接转换功能:ISA2006系列之十三
查看>>
MVC:找不到请求的 .Net Framework Data Provider
查看>>
数学建模一二
查看>>
eclipse中快捷键
查看>>
iOS / OXS LeanCloud云存储方案简单测试记录
查看>>
初尝dinnernow
查看>>
linux中生成考核用的GPT分区表结构修复案例
查看>>
综合应用WPF/WCF/WF/LINQ之三十九:实现一个简单的DataGrid之获取某格的原始(或当前)行(或列)的Index...
查看>>
SharePoint Server 2013 之一:为SharePoint启航
查看>>