SpringBoot 札记 ( Shiro整合springboot、实现登陆拦截、用户认证 )

一:新建一个springboot项目,勾选web、thymeleaf依赖

SpringBoot 札记 ( Shiro整合springboot、实现登陆拦截、用户认证 )_第1张图片

二:导入shiro-spring的依赖


        <dependency>
            <groupId>org.apache.shirogroupId>
            <artifactId>shiro-springartifactId>
            <version>1.7.1version>
        dependency>

三:编写Shiro的核心配置类

ShiroConfig 和 UserRealm

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

@Configuration
public class ShiroConfig {
   //配置Shiro的三大对象

    //三:ShiroFilterFactoryBean
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);
        return bean;
    }
    //二:DefaultWebSecurityManager
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联 UserRealm 用spring容器中拿 参数传
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    //一:创建realm对象,需自定义类
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }
}

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.context.annotation.Configuration;


// 自定义的 UserRealm 需继承 AuthorizingRealm
public class UserRealm extends AuthorizingRealm {
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了授权");
        return null;
    }
    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行了认证");
        return null;
    }
}

四:编写 待会要跳转的vip等级页面

在templates目录下新建user目录 下面新建两个页面
SpringBoot 札记 ( Shiro整合springboot、实现登陆拦截、用户认证 )_第2张图片

五:编写 控制层实现页面跳转

SpringBoot 札记 ( Shiro整合springboot、实现登陆拦截、用户认证 )_第3张图片
并在index页面 建立两个a标签实现页面跳转
SpringBoot 札记 ( Shiro整合springboot、实现登陆拦截、用户认证 )_第4张图片

六:测试功能

SpringBoot 札记 ( Shiro整合springboot、实现登陆拦截、用户认证 )_第5张图片
SpringBoot 札记 ( Shiro整合springboot、实现登陆拦截、用户认证 )_第6张图片
SpringBoot 札记 ( Shiro整合springboot、实现登陆拦截、用户认证 )_第7张图片

七:登陆拦截

ShiroConfig类 设置过滤器

@Configuration
public class ShiroConfig {
   //配置Shiro的三大对象

    //三:ShiroFilterFactoryBean
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器。。。。。

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

        return bean;
    }

效果如图所示
SpringBoot 札记 ( Shiro整合springboot、实现登陆拦截、用户认证 )_第8张图片
我们想要他 如果没有权限的话 跳转到 登陆页面 所以我们需要在设置过滤器的下面设置一个登陆请求

 //设置登陆的请求
 bean.setLoginUrl("/toLogin");

并在控制层 新添一个toLogin请求 编写一个login页面

//登陆
    @GetMapping("/toLogin")
    public String toLogin(){
        return "/login";
    }

SpringBoot 札记 ( Shiro整合springboot、实现登陆拦截、用户认证 )_第9张图片
现在 没有权限的话 点击进入 就会转到 login页面
SpringBoot 札记 ( Shiro整合springboot、实现登陆拦截、用户认证 )_第10张图片

八:用户认证

既然要登陆验证 必然需要写一个登陆的请求
在controller中

//登陆
    @GetMapping("/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) {//用户名不存在
            e.printStackTrace();
            model.addAttribute("msg","用户名错误");
            return "login";
        }catch (IncorrectCredentialsException e){//密码错误
            e.printStackTrace();
            model.addAttribute("msg","密码错误");
            return "login";
        }
    }

login页面 也让他走这个请求
SpringBoot 札记 ( Shiro整合springboot、实现登陆拦截、用户认证 )_第11张图片
其实我们的认证 是在UserRealm中实现的

 //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行了认证");
        //用户名,密码  暂时自己模拟
        String name = "csnz";
        String password = "123456";
        UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;

        if(!token.getUsername().equals(name)){
            return null;//直接抛出异常 UnknownAccountException
        }
        //密码验证,shiro 会做
        return new SimpleAuthenticationInfo("",password,"");
    }

虽然控制层和这个realm类看起来毫无关联 但是 走的请求却会来到realm类的认证方法中

你可能感兴趣的:(SpringBoot,shiro,spring,boot)