SpringBoot学习---SpringSecurity与Shiro

视频学习链接:
SpringBoot学习---SpringSecurity与Shiro_第1张图片
狂神说SpringBoot18:集成SpringSecurity

目录:

      • 一.SpringSecurity
        • 1.什么是SpringSecurity
        • 2.实际操作
          • (1) 项目框架
          • (2) 项目使用的依赖(在pom.xml中)
          • (3) 前端界面
          • (4) controller层实现页面的跳转
          • (5) SpringSecurity的使用
          • (6) 运行效果
      • 二.Apache Shiro
        • 1.什么是Apache Shiro
        • 2.三大核心组件
        • 3.四大核心功能
        • 4.实际操作
          • (1) 项目结构
          • (2) 导入依赖(在pom.xml中)
          • (3) 前端界面
          • (4) controller层实现页面的跳转
          • (5) Dao层用户的数据从数据库中获取
          • (6) Service层
          • (7) Shiro的使用
          • (8) 运行效果

一.SpringSecurity

1.什么是SpringSecurity

Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架。它实际上是保护基于spring的应用程序的标准。

2.实际操作

需求:根据用户的权限,限制用户可进入的页面,如用户权限为VIP1可以访问/level1/下的所有页面,用户权限为VIP2可以访问/level2/下的所有页面,用户权限为VIP3可以访问/level3/下的所有页面。
SpringBoot学习---SpringSecurity与Shiro_第2张图片

(1) 项目框架

SpringBoot学习---SpringSecurity与Shiro_第3张图片

(2) 项目使用的依赖(在pom.xml中)
        
        <dependency>
            <groupId>org.thymeleafgroupId>
            <artifactId>thymeleaf-spring5artifactId>
        dependency>

        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-securityartifactId>
        dependency>

        
        <dependency>
            <groupId>org.thymeleaf.extrasgroupId>
            <artifactId>thymeleaf-extras-springsecurity5artifactId>
        dependency>
(3) 前端界面

SpringBoot学习---SpringSecurity与Shiro_第4张图片
Login.html:用户登入页面

DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<form action="/index" method="post">
    <p>账号:p><input type="text" placeholder="请输入账号" name="userName">
    <p>注销:p><input type="password" placeholder="请输入密码" name="passWord">
    br>
    <input type="checkbox" name="remember">记住我
    br>
    <input type="submit" value="登入">
form>
body>
html>

index.html:网站主界面

DOCTYPE html>
<html lang="en" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<H1>首页H1>
<div class="right menu">
    
    <div sec:authorize="!isAuthenticated()">
        <a th:href="@{/tologin}" class="item"/>登入
    div>

    <div sec:authorize="isAuthenticated()">
        <a class="item">
            用户名: <span sec:authentication="name">span>
            角色:<span sec:authentication="principal.authorities">span>
        a>
    div>

    <div sec:authorize="isAuthenticated()">
        <a th:href="@{/logout}"  class="item"/>注销
    div>
div>

<div sec:authorize="hasRole('VIP1')">
    <h2>level1h2>
    <a href="/level1/1">level1-1a>
    <a href="/level1/2">level1-2a>
    <a href="/level1/3">level1-3a>
div>

<div sec:authorize="hasRole('VIP2')">
    <h2>level2h2>
    <a href="/level2/1">level2-1a>
    <a href="/level2/2">level2-2a>
    <a href="/level2/3">level2-3a>
div>

<div sec:authorize="hasRole('VIP3')">
    <h2>level3h2>
    <a href="/level3/1">level3-1a>
    <a href="/level3/2">level3-2a>
    <a href="/level3/3">level3-3a>
div>

body>
html>

/leve1/X.html随便写写即可
SpringBoot学习---SpringSecurity与Shiro_第5张图片

(4) controller层实现页面的跳转

SecurityProjectController类:
SpringBoot学习---SpringSecurity与Shiro_第6张图片

(5) SpringSecurity的使用

经过前面操作,基本上可以实现界面的跳转,但是还无法实现根据用户权限的不同,展示不同的页面,这个时候我们需要使用SpringSecurity。

  • 导入SpringSecurity的依赖
    SpringBoot学习---SpringSecurity与Shiro_第7张图片
  • 在config中创建SecurityConfig类(自定义Spring Security 配置类)
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    // 授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 定制请求的授权规则
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("VIP1")
                .antMatchers("/level2/**").hasRole("VIP2")
                .antMatchers("/level3/**").hasRole("VIP3");
        // 开启登入
        http.formLogin().loginPage("/tologin").usernameParameter("userName").passwordParameter("passWord").loginProcessingUrl("/index");
       // 注销
        http.logout().logoutSuccessUrl("/tologin");
        http.csrf().disable();
        // 开启记住我功能
        http.rememberMe().rememberMeParameter("remember");
    }


    // 认证
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
       // 从内存中定义
        auth.inMemoryAuthentication()
                .passwordEncoder(new BCryptPasswordEncoder())
                .withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("VIP1")
                .and()
                .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("VIP2")
                .and()
                .withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("VIP3");
    }
}

WebSecurityConfigurerAdapter:自定义Security策略(自定义Spring Security 配置类继承该类即可)
在这里插入图片描述

@EnableWebSecurity:开启WebSecurity模式
SpringBoot学习---SpringSecurity与Shiro_第8张图片

AuthenticationManagerBuilder:自定义认证策略
SpringBoot学习---SpringSecurity与Shiro_第9张图片
Spring Security的两个主要目标是 “认证” 和 “授权”(访问控制):
重写configure(HttpSecurity http)方法用于授权
SpringBoot学习---SpringSecurity与Shiro_第10张图片
重写configure(AuthenticationManagerBuilder auth)方法用于认证
SpringBoot学习---SpringSecurity与Shiro_第11张图片

(6) 运行效果

SpringBoot学习---SpringSecurity与Shiro_第12张图片
这个登入界面是使用自己编写的(SpringSecurity本身提供登入界面)
SpringBoot学习---SpringSecurity与Shiro_第13张图片
登入admin(权限为VIP1)

SpringBoot学习---SpringSecurity与Shiro_第14张图片
SpringBoot学习---SpringSecurity与Shiro_第15张图片
登入root(权限为VIP2)
SpringBoot学习---SpringSecurity与Shiro_第16张图片
登入guest用户(权限为VIP3)
SpringBoot学习---SpringSecurity与Shiro_第17张图片

二.Apache Shiro

1.什么是Apache Shiro

Apache Shiro是一个功能强大且易于使用的Java安全框架,提供了认证,授权,加密,和会话管理。如同 Spring security 一样都是是一个权限安全框架,但是与Spring Security相比,在于他使用了和比较简洁易懂的认证和授权方式。

2.三大核心组件

  • subject:主体,可以是用户也可以是程序,主体要访问系统,系统需要对主体进行认证、授权。
  • securityManager: 安全管理器,主体进行认证和授权都是通过它进行。
  • realm:领域,可以理解为DAO,通过它存取认证、授权相关数据。

3.四大核心功能

  • Authentication:认证即登录,用于用户身份识别。
  • Authorization: 授权即访问控制,判断用户是否有权限去访问受保护的资源。
  • Cryptography: 通过加密算法保护数据安全。
  • Session Management:会话管理,即用户访问你应用自身携带的数据,甚至可以在非Web程序

4.实际操作

需求:通过查询用户的perms字段的值,如果为user:add表示该用户可以进入add.html;如果为user:update表示该用户进入update.html
SpringBoot学习---SpringSecurity与Shiro_第18张图片

(1) 项目结构

SpringBoot学习---SpringSecurity与Shiro_第19张图片

(2) 导入依赖(在pom.xml中)
        <!--导入shiro依赖-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.1</version>
        </dependency>

        <!--数据库-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.12</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>
(3) 前端界面

SpringBoot学习---SpringSecurity与Shiro_第20张图片
index.html:网站首页界面

<!DOCTYPE html>
<html lang="en"
      xmlns:th="https://www.thymeleaf.org"
      xmlns:shiro="https://shiro.apache.org/jsp-tag-library.html">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<h1>首页</h1>
<p th:text="${msg}" style="color: red;"></p>

<shiro:notAuthenticated>
  <a th:href="@{/toLogin}">登入</a>
</shiro:notAuthenticated>

<shiro:authenticated>  
  
  <shiro:haspermission name="user:add">
    <a th:href="@{/user/add}">add</a>
  </shiro:haspermission>


  <shiro:haspermission name="user:update">
    <a th:href="@{/user/update}">update</a>
  </shiro:haspermission>

</shiro:authenticated>

</body>
</html>



login.html:用户登入界面

<!DOCTYPE html>
<html lang="en"  xmlns:shiro="https://www.thymeleaf.org/thymeleaf-extras-shiro">
<head>
    <meta charset="UTF-8">
    <title>登入界面</title>
</head>
<body>
<form th:action="@{/submitLogin}" method="post">
    <p th:text="${msg}" style="color: red;"></p>
   账号:<input type="text" name="userName">
  密码:<input type="password" name="passWord">
   <input type="submit" value="登入">
</form>
</body>
</html>

User下的add.html和update.html随便写写即可:
SpringBoot学习---SpringSecurity与Shiro_第21张图片

(4) controller层实现页面的跳转
@Controller
public class MyController {
    @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("/submitLogin")
    public String login(@RequestParam("userName") String username, @RequestParam("passWord")String passWord, Model model){
        // 获取当前对象
        Subject subject = SecurityUtils.getSubject();
        // 封装用户的登入数据
        UsernamePasswordToken token =new UsernamePasswordToken(username,passWord);
        System.out.println("进行登入!");
        try {
            subject.login(token);// 执行登入方法
            return "index";
        }catch (UnknownAccountException e){
            model.addAttribute("msg","用户名错误");
            return "login";
        }catch (IncorrectCredentialsException e){
            model.addAttribute("msg","密码错误");
            return "login";
        }
    }


    @ResponseBody
    @RequestMapping("/auth")
    public String noauth(){
        return  "没有授权!";
    }


}

这里注意登入使用的Subject对象进行登入:
SpringBoot学习---SpringSecurity与Shiro_第22张图片

(5) Dao层用户的数据从数据库中获取

数据表结构:
SpringBoot学习---SpringSecurity与Shiro_第23张图片
数据:
SpringBoot学习---SpringSecurity与Shiro_第24张图片
数据源配置application.yaml中:

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver

pojo:
SpringBoot学习---SpringSecurity与Shiro_第25张图片

Mapper层:
SpringBoot学习---SpringSecurity与Shiro_第26张图片
SpringBoot学习---SpringSecurity与Shiro_第27张图片
不要忘了扫描一下包:
application.properties中
SpringBoot学习---SpringSecurity与Shiro_第28张图片
由于映射文件UserMapper.xml放在Java文件中(资源过滤),不然无法生成该UserMapper.xml:

        <resource>
                <directory>src/main/javadirectory>
                <includes>
                    <include>**/*.xmlinclude>
                includes>
            resource>

SpringBoot学习---SpringSecurity与Shiro_第29张图片

(6) Service层

UserService接口:
SpringBoot学习---SpringSecurity与Shiro_第30张图片
UserServiceImpl实现类:
SpringBoot学习---SpringSecurity与Shiro_第31张图片

(7) Shiro的使用
  • ShiroConfig配置

三个bean对象:(userRealm,DefaultWebSecurityManager,ShiroFilterFactoryBean)

@Configuration
public class ShiroConfig {
    // ShiroFilterFactoryBean
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        // 设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);
        // 添加shiro的内置过滤器
        Map<String,String> filterMap =new LinkedHashMap<>();
        filterMap.put("/user/add","perms[user:add]");
        filterMap.put("/user/update","perms[user:update]");
        filterMap.put("/user/*","authc");
        bean.setFilterChainDefinitionMap(filterMap);
        // 设置登入页面
        bean.setLoginUrl("/toLogin");
        bean.setUnauthorizedUrl("/auth");
        return bean;
    }

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


    // 创建realm对象
    @Bean
    public UserRealm userRealm() {
        return new UserRealm();
    }

    @Bean
    public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }
}


  • 授权与认证userService类
public class UserRealm extends AuthorizingRealm {
    @Autowired
    private UserServiceImpl userService;
    // 授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
       System.out.println("执行了=>授权doGetAuthorizationInfo");
       // 进行授权
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        // 通过数据库授权
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipal();
        info.addStringPermission(user.getPerms());
        return info;
    }

    // 认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("执行了=>验证doGetAuthenticationInfo");
//        // 获取用户名,密码
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        User user = userService.getUserByName(userToken.getUsername());
        if (user == null){
            return null;
        }

        // 密码验证
        return new SimpleAuthenticationInfo(user,user.getPwd(),"");
    }
}

(8) 运行效果

SpringBoot学习---SpringSecurity与Shiro_第32张图片

登入admin用户(只有add权限):
SpringBoot学习---SpringSecurity与Shiro_第33张图片
SpringBoot学习---SpringSecurity与Shiro_第34张图片

SpringBoot学习---SpringSecurity与Shiro_第35张图片

登入测试(只有update权限):

SpringBoot学习---SpringSecurity与Shiro_第36张图片
SpringBoot学习---SpringSecurity与Shiro_第37张图片
SpringBoot学习---SpringSecurity与Shiro_第38张图片

你可能感兴趣的:(Spring全家桶,spring,boot,学习,java,SpringSecurity,Shiro)