Springboot整合shiro

1.首先理解shiro的三大核心要素:subject 用户、securityManager 管理所有用户、realm 连接数据库
2.idea创建springboot项目,导入shiro依赖

<dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.8.0</version>
        </dependency>

3.创建Reaml类,添加以下代码

public class UserRealm extends AuthorizingRealm {
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        return null;
    }
}

接着创建ShiroConfig类,添加如下代码

@Configuration
public class ShiroConfig {
    //shiroFilterFactoryBean:3
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean
    (@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);
        return bean;
    }

    //DefaultWebSecurityManager:2
    /*  在使用@Autowire自动注入的时候,加上@Qualifier(“test”)可以指定注入哪个对象
        可以作为筛选的限定符,我们在做自定义注解时可以在其定义上增加@Qualifier,用来筛选需要的对象。
     */
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联realm
        securityManager.setRealm(userRealm);
        return securityManager;
    }

    //Real 对象,需要自定义:1
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }
}

4.实现登陆拦截,在shiroconfig类中的shiroFilterFactoryBean方法中加入以下代码

//添加shiro的内置过滤器
        /*
        anon:无需认证就可以访问
        authc:必须认证了才能访问
        user:必须拥有记住我功能才能用
        perms:拥有对某个资源的权限才能访问
        role:拥有某个角色权限才能访问
         */
        Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/**","XXX");
        filterMap.put("/**","XXX");
        bean.setFilterChainDefinitionMap(filterMap);

        //设置登录的请求
        //这里注意toLogin对应controller中的RequestMapping
        bean.setLoginUrl("/toLogin");

5.实现用户认证,首先在controller下添加如下代码

 @RequestMapping("/login")
    public String login(String username,String password,Model model){
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //封装用户的登录数据,令牌加密
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        //捕获登录异常
        try{
            subject.login(token);//执行登录方法
            return "index";
        }catch (UnknownAccountException e){
            model.addAttribute("msg","用户名错误");
            return "login";
        }catch (IncorrectCredentialsException e){
            model.addAttribute("msg","密码错误");
            return "login";
        }

然后在UserRealm类中的doGetAuthenticationInfo方法认证中加入如下代码

//用户名,密码 从数据库中取,这里采用模拟数据库操作
        String name ="XXX";
        String password = "XXX";
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;

        if(!userToken.getUsername().equals(name)){
            return null; //抛出异常 UnKnowAccountException
        }
        //密码认证,shiro做
        return new SimpleAuthenticationInfo("",password,"");
    }

先执行try中的login方法,跳到doGetAuthenticationInfo方法中,再返回try捕捉异常

6.整合Mybatis,先添加依赖

<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

编写yml配置,数据库、mybatis、druid相关操作
接着完善项目,建立pojo、mapper、service层
service接口类跟mapper类中的方法一样

@Service
public class UserServiceImpl implements UserService{
    @Autowired
    UserMapper userMapper;
    @Override
    public User queryUserByName(String user_name) {
        return userMapper.queryUserByName(user_name);
    }
}

修改UserRealm配置类

 UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        //连接数据库
        User user = userService.queryUserByName(userToken.getUsername());
        //密码认证,shiro做
        if(user==null){
            return null;
        }
        return new SimpleAuthenticationInfo("",user.getUser_password(),"");

7.实现功能授权,首先在shiroconfig配置类中的shiroFilterFactoryBean下,添加需授权的页面

//授权,正常情况下没有授权跳到说明未授权页面
        filterMap.put("/add","perms[user:add]");
        filterMap.put("/update","perms[user:update]");

针对未授权页面需跳到提示页面,并在shiroFilterFactoryBean下,添加未授权页面路径请求

//未授权页面
        bean.setUnauthorizedUrl("/unauthorized");

接着针对用户表添加一个权限列
针对登录后的用户,拿到其所拥有的权限,修改doGetAuthenticationInfo方法中return new SimpleAuthenticationInfo(user,user.getUser_password(),"");以此来获得用户
在UserReaml配置类中的doGetAuthorizationInfo方法中添加如下代码

SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //拿到当前的对象
        Subject subject = SecurityUtils.getSubject();
        User currentUser = (User) subject.getPrincipal();
        //设置当前用户的权限
        info.addStringPermission(currentUser.getPerms());
        return info;

8.shiro整合thymeleaf,导入依赖thymeleaf-extras-shiro
在shiroconfig配置类中加入以下代码

 //整合shiroDialect: 用来整合shiro thymeleaf
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }

在页面中加入以下代码

xmlns:shiro="http://www.thymeleaf.org/extras/shiro"

<div shiro:hasPermission="user:add">
#控制页面哪些功能只能登录授权后才可以显示

对于登录后的登录按钮的隐藏,可以用session进行获取,而session配置代码可以放在获取用户信息步骤后的模块中

Subject currentSubject = SecurityUtils.getSubject();
        Session session = currentSubject.getSession();
        session.setAttribute("loginUser",user);

然后在登录盒子内进行判断

<div th:if="${session.loginUser}==null">
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值