shiro讲解,以及SpringBoot微框架集成shiro完成登录拦截器功能。

一:shiro是什么?

1.shiro是什么

    shiro是apache开源组织开发的一套开源的安全(权限)框架,跨语言跨平台,能在B/S架构上运行,也能在C/S架构上运行。

2.shiro与传统权限的区别

shiro是对传统的五表权限进行了封装,shiro把用户的认证(登录)和授权(用户赋权限)功能进行了封装处理,使权限操作更加简便,shiro需要传统五表权限来维护用户 角色 权限之间的关系。

3.shiro的原理(运行流程)

   securityManager  安全管理中心(shiro的所有操作都由它来完成)

   Authenticator  认证 (登录)

   Authorizer 授权(使用当前登录用户的id到数据库中查询用户所拥有的权限)

   Realm 域  用来连接关系型数据库 执行对应的sql语句

   Subject 主体 当前的登录用户 相当于五表权限中的session

认证流程:

二:SpringBoot微框架集成shiro完成登录拦截器功能。

认证流程:

1.首先在pom.xml配置文件中引入shiro所需要的jar包

    <!--shiro所需要的jar包-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>

2.包结构下创建子包shiro,创建类为ShiroConfig

ShiroConfig:

package com.jk.shiro;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.shiro.mgt.SecurityManager;

import java.util.LinkedHashMap;
import java.util.Map;

@Configuration//把当前类 作为spring配置文件使用
public class ShiroConfig {


    /**
     * shiro 的过滤器链
     *       shiro的核心总入口
     *
     * */
    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {

        System.out.println("ShiroConfiguration.shirFilter()");
        // shiro过滤器工厂
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        // 必须设置 SecurityManager 如果不设置就无法完成认证和授权
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        // 过滤器链
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();

        // 配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
        // logout shiro定义好的过滤器名字 /logout访问路径
        // 浏览器访问的地址栏路径中以/logout结尾的路径 走logout过滤器
        // logout会清除session 退出登录
        //第一个参数是前台发送的路径
        filterChainDefinitionMap.put("/logout", "logout");
        // 所有的css文件走  anon过滤器 此过滤器代表放过拦截 不需要权限也能访问
        filterChainDefinitionMap.put("/css/**", "anon");
        // 放过登录页面拦截
        filterChainDefinitionMap.put("/toLogin", "anon");
        filterChainDefinitionMap.put("/img/**", "anon");
        filterChainDefinitionMap.put("/js/**", "anon");
        /// **代表所有路径 除以上路径外都拦截 authc代表权限拦截过滤器
        filterChainDefinitionMap.put("/**", "authc");
        // perms权限过滤器 必须拥有某项权限才能访问对应路径
        // filterChainDefinitionMap.put("/add", "perms[user:query]");
        // 登录请求路径 登录页面提交form表单时 表单的action写此路径
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 登录成功跳转到登录成功页面
        shiroFilterFactoryBean.setSuccessUrl("/index");
        // 未授权界面;
        //shiroFilterFactoryBean.setUnauthorizedUrl("/warning");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        // 最终返回过滤器链
        return shiroFilterFactoryBean;

    }



    @Bean // 在xml文件中配置一个bean标签 相当于<bean class="
    // org.apache.shiro.mgt.SecurityManager"
    // name="securityManager"></bean>
    public SecurityManager securityManager() {

        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();

        // 设置realm. 域(数据源 用来连接数据库完成认证和授权)
        // 把自己创建的Realm 注入到securityManager中
        securityManager.setRealm(myShiroRealm());

        // 注入缓存管理器;
        //securityManager.setCacheManager(ehCacheManager());//
        // 这个如果执行多次,也是同样的一个对象;
        // securityManager.setRememberMeManager(rememberMeManager());

        return securityManager;

    }

    @Bean
    public MyRealm myShiroRealm(){
        return new MyRealm();
    }
}

3.接着在shiro包中手动创建realm,MyRealm类

package com.jk.shiro;

import com.jk.model.UserBean;

import com.jk.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;


public class MyRealm extends AuthorizingRealm {

    //注入Servie层
    @Autowired
    private UserService userService;

    //认证方法
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //获取到输入框输入的用户名
        String userName = (String)token.getPrincipal();
        //去后台查是否有此账号
        UserBean user = userService.queryUserByName(userName);
        //判断账号是否存在
        if(user == null){
            //如果用户对象为空 抛出用户名错误异常
            throw new UnknownAccountException();
        }
        //认证器 第一个参数为用户名或用户对象 第二个参数为密码 第三个参数为当前real名称
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userName,user.getPassword(),this.getName());
        return simpleAuthenticationInfo;
    }

    //授权方法
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }
}

4.创建LoginController写自己的登录逻辑

package com.jk.controller;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UnknownAccountException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

@Controller
public class LoginController {

    /**
     * 当用户名密码不正确时
     * 跳转到此方法
     * 认证失败之后会进入此方法 提示用户失败原因
     * @return
     */
    @RequestMapping("login")
    public String login(HttpServletRequest request, ModelMap map){
        //认证器会根据对应的错误 返回对应的异常 根据异常判断对应错误
        String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");

        if(UnknownAccountException.class.getName().equals(exceptionClassName)
                || AuthenticationException.class.getName().equals(exceptionClassName)){
            System.out.println("request = [ 用户名异常]");
            map.put("message","用户名错误");
        }else{
            System.out.println("request = [密码异常]");
            map.put("message","密码错误");
        }
        return "login";
    }
    @RequestMapping("toLogin")
    public String toLogin(){
        //登陆页面
        return "login";
    }
    @RequestMapping("index")
    public String toIndex(){
        //主页面
        return "main";
    }
}

5.templates文件夹下创建login登录页面

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Insert title here</title>
</head>
<body>
      <!--action="login" 写配置文件中的LoginUrl中内容  -->
      <form action="login" method="post">
           <!--username shiro默认的用户名属性  -->
           <input type="text" name="username"/><br/>
           <!--password shiro默认的密码属性 -->
           <input type="password" name="password"/><br/>
           <input type="submit" value="登录"/><br/>
      </form>
</body>
</html>

6.访问http://localhost:8080(你的端口号)/tologin 完成登录

完毕!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

听风动

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值