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中判断账户密码了,这里只是简单的应用,详细还是请君奋力!
项目结构