[SpringBoot+Shiro] 简单实现验证+授权案例

目录

  • Spring Boot
  • Shiro
  • Thymeleaf
  • Mybatis Plus (也可以自己选择使用其他访问数据库数据的方法)

  • ShiroConfig.java
@Configuration
public class ShiroConfig {
    //ShiroFilterFactoryBean 第三步 注入第二步的DefaultWebSecurityManager
    @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]"); //要有user:add的权限才能访问/user/add页面,从数据库中获取校验
        filterMap.put("/user/update","perms[user:update]"); //要有user:update的权限才能访问/user/update页面,从数据库中获取校验
        filterMap.put("/user/*","authc");   //所有user下的请求都需要经过用户认证才阔以访问
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap); //设置过滤拦截map
        shiroFilterFactoryBean.setLoginUrl("/toLogin"); //设置登录请求的页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/noauth"); //设置未经授权跳转的页面
        return shiroFilterFactoryBean;
    }
    //DefaultWebSecurityManager 第二步 注入第一步的real
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联Realm
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    //创建real对象,需要自定义    第一步
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }
}
  • UserRealm.java
//自定义的UserRealm
public class UserRealm extends AuthorizingRealm {

    //自动注入Service
    @Autowired
    UserService userService;

    //访问授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了授权=》doGetAuthorizationInfo");

        //SimpleAuthorizationInfo
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        //拿到当前登录的对象,从下面认证中拿,new SimpleAuthenticationInfo(user,user.getPassword(),""); 中的第一个参数user
        Subject subject = SecurityUtils.getSubject();
        //拿到经过了认证的当前对象User
        User currentUser = (User) subject.getPrincipal();
        //为当前用户添加的权限,从数据库中获取的字段权限
        info.addStringPermission(currentUser.getPerms());
        return info;
    }

    //登录认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行了认证=》doGetAuthorizationInfo");
        //获取经过controller登录封装的token
        UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;
        String username = userToken.getUsername();
        //从数据库中查找登录用户的信息 这里我使用了MyBatis Plus的方法
        User user = userService.getOne(new QueryWrapper<User>().eq("username", username), false);
        System.out.println("user:" + user);
        //用户名验证
        if (!userToken.getUsername().equals(user.getUsername())) {
        //抛出异常 UnknownAccountException 用户名不存在
            return null;
        }
        //密码验证 shiro会自己去做,这里的第一个参数,传进来,之后通过SecurityUtils.getSubject(); subject.getPrincipal();  就可以获得这个user对象
        return new SimpleAuthenticationInfo(user, user.getPassword(), "");
    }
}
  • ShiroConroller.java
@Controller
public class ShiroController {
    //返回主页
    @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";
    }
    //返回登录页面
    @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 {
            subject.login(token);
            return "index";
        }catch (UnknownAccountException e){
            model.addAttribute("msg","用户名错误");
            return "login";
        }catch (IncorrectCredentialsException e){
            model.addAttribute("msg","密码错误");
            return "login";
        }
    }
    //没有经过授权的页面
    @RequestMapping("/noauth")
    @ResponseBody
    public String Unauthorized(){
        return "未经授权,不能访问该页面";
    }
}
  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>shiro-springboot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>shiro-springboot</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- shiro整合spring的包 -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-java8time</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--mp-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--mp代码生成器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-tools</artifactId>
            <version>2.0</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
  • index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>首页</h1>
    <p th:text="${msg}"></p>
    <a th:href="@{/user/add}">add</a>
    <a th:href="@{/user/update}">update</a>
</body>
</html>
  • login.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>login</h1>
<p th:text="${msg}" style="color: red"></p>
<form th:action="@{/login}">
    <p>用户名:<input type="text" name="username"></p>
    <p>密码:<input type="text" name="password"></p>
    <p><input type="submit"></p>
</form>
</body>
</html>

  • 登录页

  • add页(需经过认证和授权)

  • update页(需经过认证和授权)

  • 未经授权页

  • 数据库

!

posted @ 2020-09-23 14:37  lodalo  阅读(416)  评论(0编辑  收藏  举报