Shiro学习小结

第一步:导包

<!--        shiro整合spring-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>
<!--      shiro整合thymeleaf  -->
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>
<!--        日志-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
<!--        thymeleaf-->
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
        </dependency>
        <!--使用Spring Boot和Thymeleaf,并且需要在视图中格式化Java 8 Date&Time对象,下一步就是将方言添加到模板引擎-->

        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-java8time</artifactId>
        </dependency>

        <!--        驱动-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!--        数据源-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.6</version>
        </dependency>
        <!--        mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>
        <!--        web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--        构造函数-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--连接数据库-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--        测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

第二步:Realm和ShiroConfig

Realm:

public class UserRealm extends AuthorizingRealm {
    @Autowired
    UserService userService;

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.out.println("执行了=》授权");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //当前登录对象
        Subject subject = SecurityUtils.getSubject();
        User currentUser = (User)subject.getPrincipal();//是getPrincipal而不是getPrincipals
        //设置当前用户权限
        info.addStringPermission(currentUser.getPerms());

        return info;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("执行了==》认证");
        //点击登录就会走这个方法,然后点击其他页面的时候走上边的授权方法
        //用户名,密码 数据库中去取
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        //链接真是数据库
        User user = userService.getUserByName(userToken.getUsername());

        System.out.println(user);
        //用户认证

        if (user==null){
            System.out.println("账号验证!");
            return null;//抛出异常UnknownAccountException e

        }
        //登陆成功
        System.out.println("账号验证通过");

        //当前登陆对象
        Subject currentSubject = SecurityUtils.getSubject();
        Session session = currentSubject.getSession();
        session.setAttribute("loginUser",user);


        //密码认证 shiro自动执行
        System.out.println("密码验证");
        return new SimpleAuthenticationInfo(user,user.getPassword(),"");

    }

ShiroConfig:

@Configuration
public class ShiroConfig {
    //创建realm对象(授权认证的对象),需要自定义:1
    @Bean(name = "userRealm")
    public UserRealm userRealm() {
        UserRealm userRealm = new UserRealm();
        return userRealm;
    }

    //DefaultWebSecurityManager:2
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getdefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联realm
        securityManager.setRealm(userRealm);
        return securityManager;
    }

//    ShiroFilterFactoryBean:3
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        //添加shiro的内置过滤器
        /*
        anon:无需认证就可以访问
        authc:必须认证了才能访问
        user:必须有  记住我 功能才能访问
        perms:拥有了对某个资源的权限访问才能访问
        role:拥有了某个角色才能访问
         */
        //登录拦截
        Map<String,String> filterMap = new LinkedHashMap<>();
        //授权,正常的情况下,没有授权会跳转到未授权页面
        filterMap.put("/user/add","perms[user:add]");
        filterMap.put("/user/update","perms[user:update]");

        filterMap.put("/user/*","authc");//必须认证了才能访问
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);

        //设置登陆的请求,请求被拦截后的跳转界面
        shiroFilterFactoryBean.setLoginUrl("/toLogin");
        //未授权页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/unauth");
        return shiroFilterFactoryBean;
    }

    //整合ShiroDialect:用来整合shiro thymeleaf
    //实现shiro想要实现的前端页面显示
    @Bean
    public ShiroDialect getShiroDialect() {
        return new ShiroDialect();
    }


}

Controller:

@Controller
public class UserController {

//    @Autowired
//    private UserService userService;
//    @RequestMapping("/user")
//    public String user(){
//        User user = userService.getUserById(1);
//        System.out.println(user);
//        return "select user succed!";
//    }
    //用Model向前端页面传输
    @RequestMapping({"/","/index"})
    public String toIndex(Model model){
        model.addAttribute("msg","hello shiro");
        return "index";
    }
    @RequestMapping("/user/add")
    public String add(){return "user/add";}
    @RequestMapping("/user/update")
    public String update(){return "user/update";}
    //shiro设定的登陆界面(默认界面)
    @RequestMapping("/toLogin")
    public String toLogin(){
        return "login";
    }

    //前端登录界面输入账号密码之后到这儿处理
    @RequestMapping("/login")
    public String login(String username,String password,Model model){
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //封装用户的登陆数据
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            System.out.println("执行登陆的方法");
            subject.login(token);//执行登陆的方法(走UserRealm的认证)
            System.out.println("登陆成功");
            return "index";//登陆成功
        }catch (UnknownAccountException e){
            System.out.println("没有此用户");
            model.addAttribute("msg","用户名错误");
            return "login";//继续登录
        }catch (IncorrectCredentialsException e){
            System.out.println("密码错误");
            model.addAttribute("msg","密码错误");
            return "login";//继续登录
        }

    }
    @RequestMapping("/unauth")
    @ResponseBody
    @ExceptionHandler(value = {UnauthorizedException.class})
    public String unauthorized(){return "未经授权禁止访问!";}

后台处理流程:

1.首先前端页面走这里

@RequestMapping({"/","/index"})
public String toIndex(Model model){
    model.addAttribute("msg","hello shiro");
    return "index";
}

2.点击登陆之后,跳转到这个页面:

//前端登录界面输入账号密码之后到这儿处理
@RequestMapping("/login")
public String login(String username,String password,Model model){
    //获取当前用户
    Subject subject = SecurityUtils.getSubject();
    //封装用户的登陆数据
    UsernamePasswordToken token = new UsernamePasswordToken(username, password);
    try {
        System.out.println("执行登陆的方法");
        subject.login(token);//执行登陆的方法(走UserRealm的认证)
        System.out.println("登陆成功");
        return "index";//登陆成功
    }catch (UnknownAccountException e){
        System.out.println("没有此用户");
        model.addAttribute("msg","用户名错误");
        return "login";//继续登录
    }catch (IncorrectCredentialsException e){
        System.out.println("密码错误");
        model.addAttribute("msg","密码错误");
        return "login";//继续登录
    }

}

3.输入账号密码点击登录后:

subject.login(token);//执行登陆的方法(走UserRealm的认证)----》Realm的认证,如果有此用户继续验证密码是否正确,如果正确,显示下一个页面,如果不正确抛出异常,走这里------》
catch (IncorrectCredentialsException e){
    System.out.println("密码错误");
    model.addAttribute("msg","密码错误");
    return "login";//继续登录
}

如果所查用户数据库中不存在,走这里-----》

catch (UnknownAccountException e){
    System.out.println("没有此用户");
    model.addAttribute("msg","用户名错误");
    return "login";//继续登录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值