springsecurity

这是一个安全框架,通过授予用户特定的访问权限,访问特定的资源,这里结合jdbc从中获取权限验证

使用技术:thymeleaf+sercurity+springBoot+Mybatis-plus+mysql+Durid数据链接池

注意:在刚刚导入依赖时候,直接启动项目,访问login页面,是security自带的,可以试试,账户是user,密码在控制台随机生成的密码!

1.导入依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
            <version>3.0.4.RELEASE</version>
        </dependency>
    </dependencies>
  • springsecurity5:这个包是为了前段页面规定哪些显示,或者哪些隐藏用的

2.创建数据库

create table form
(
    id       INT(10) auto_increment comment '登录id'
        primary key,
    username VARCHAR(10) not null comment '账户名',
    password VARCHAR(15) not null comment '登录密码
',
    role     VARCHAR(20) null comment '权限角色名'
)
    comment '登录表单';

create unique index from_id_uindex
    on form (id);
1,admin,admin,"vip1,vip2,vip3"
2,root,root,"vip1,vip2"
3,user,123,vip1

3.编写配置文件application.yml

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/mrxu?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
      username: root
      password: root
mybatis-plus:
  type-aliases-package: com.xu.pojo
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

这里配置了mybatis-plus自带的日志

4.编写3个html

  • login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页</title>
</head>
<body>
<form action="/index" method="post">
    <table>
        <tr>
            <td>用户名:</td>
            <td><input type="text" name="username"></td>
        </tr>
        <tr>
            <td>密 码:</td>
            <td><input type="password" name="password"></td>
        </tr>
        <tr>
            <td><input type="submit" value="登录"></td>
        </tr>
    </table>
</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>首页</title>
</head>
<body>
登陆成功!<a href="/a" sec:authorize="hasAnyAuthority('vip2')">vip2请点我</a><br>
<a href="/logout">点我注销</a>
</body>
</html>

**这里就是导入之前那个springsecurity5的作用,同时还要加入命名空间 **

xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"

这句sec:authorize="hasAnyAuthority(‘vip2’)"意思是,权限中有任意包含一个vip2就显示,否则隐藏

  • a.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vip2</title>
</head>
<body>
vip2欢迎
</body>
</html>

5.编写实体类Form

package com.xu.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Form implements Serializable {
    private int id;
    private String username;
    private String password;
    private String role;
}

6.编写FormMapper

package com.xu.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xu.pojo.Form;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface FormMapper extends BaseMapper<Form> {
}

7.编写LoginController

package com.xu.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class LoginController {
    @RequestMapping("/login")
    public String toLogin(){
        System.out.println("进入登录页跳转");
        return "login";
    }

    @PostMapping("/index")
    public String toIndex(){
        System.out.println("进入首页跳转");
        return "index";
    }

    @GetMapping("/a")
    public String toVip2(){
        return "a";
    }
}

8.编写SecurityConfig

package com.xu.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //登录页配置
        http.formLogin().
                //这是指定我们的登录页面
                loginPage("/login").
                //这是指定登录成功后的跳转链接,一般是form表单的action链接
                loginProcessingUrl("/index").
                //这是跳转成功后,URl地址显示
                successForwardUrl("/index").
                //这是跳转失败后,url地址栏显示
                failureForwardUrl("/login");

        //这是url链接访问的设置
        http.authorizeRequests()
                //login这个链接所有人可以访问,不需要权限,相当于放行
                .antMatchers("/login").permitAll()
                //这里给定访问a链接需要的权限是vip,才能跳转访问
                .antMatchers("/a").hasAnyAuthority("vip2")
                //这里拦截所有的请求,进入逻辑验证,相当于一个过滤器,拦截了恶意访问首页
                .anyRequest().authenticated();
        //这是注销操作,注销登录
        http.logout().logoutSuccessUrl("/login");
        //关闭csrf功能:跨站请求伪造,默认只能通过post方式提交logout请求
        http.csrf().disable();
    }
    
    //加密容器
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

}

PasswordEncoder这个注入容器托管,是为了后面的逻辑验证进行密码加密使用

9.编写我们的逻辑验证FormService

package com.xu.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xu.mapper.FormMapper;
import com.xu.pojo.Form;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

@Service
public class FormService implements UserDetailsService {
    @Autowired
    FormMapper formMapper;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.out.println("进入逻辑判断");
        if (username==null) {
            throw new UsernameNotFoundException("用户名为空!");
        }
        QueryWrapper<Form> wrapper = new QueryWrapper<>();
        wrapper.eq("username",username);
        Form form = formMapper.selectOne(wrapper);

        String password = passwordEncoder.encode(form.getPassword());
        System.out.println(form.getRole());
        return new User(username,password, AuthorityUtils.commaSeparatedStringToAuthorityList(form.getRole()));
    }
}

请注意这个放回的user类,是哪个包下的,这不是自己写的类!

然后启动我们的项目访问测试即可!


总结:

使用security时,如果没有重新配置他的逻辑判断,每次重启都是在控制台随机生成密码的,使用此框架后方便了账户和密码的判断,不用在controlelr中判断账户密码了,这里只是简单的应用,详细还是请君奋力!

项目结构

j_spring_security_check 在那个包下面_html