SpringBoot+SpringSecurity实现基于真实数据的授权认证

网友投稿 787 2023-01-23

SpringBoot+SpringSecurity实现基于真实数据的授权认证

SpringBoot+SpringSecurity实现基于真实数据的授权认证

(一)概述

Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架,Spring Security主要做两个事情,认证、授权。我之前写过一篇关于SpringSecurity的博客,但是当时只是介绍了基于mock数据的案例,本期就来介绍一下基于真实数据的认证授权实现。

(二)前期项目搭建

为了更好的展示SpringSecurity,我们先搭建一个简单的web项目出来。引入thymeleaf依赖

org.springframework.boot

spring-boot-starter-thymeleaf

org.thymeleaf

thymeleaf-spring5

org.thymeleaf.extras

thymeleaf-extras-java8time

新建一个登陆页,一个首页,然后几个不同等级的展示页面:

login.html

index.html

登陆

level-1-1

level-1-2

level-2-1

level-2-2

level-3-1

level-3-2

另外还有几个不同等级的页面

分别在body中写上自己对应的编号。

level-1-1

最后编写一个controller来接收请求:

@Controller

public class RouteController {

@RequestMapping({"/","/index"})

public String index(){

return "index";

}

@RequestMapping("/login")

public String toLogin(){

return "login";

}

@RequestMapping("/level1/{id}")

public String level1(@PathVariable("id")String id){

return "level1/"+id;

}

@RequestMapping("/level2/{id}")

public String level2(@PathVariable("id")String id){

return "level2/"+id;

}

@RequestMapping("/level3/{id}")

public String level3(@PathVariable("id")String id){

return "level3/"+id;

}

}

最终的效果如下:

最终实现等级不同的level页面根据不同权限进行跳转。

后台基于Mybatis和mysql数据库实现,因此我们除了引入SpringSecurity的依赖之外,还需要引入Mybatis相关依赖:

org.springframework.boot

spring-boot-starter-security

org.springframework.boot

spring-boot-starter-jdbc

mysql

mysql-connector-java

runtime

org.mybatis.spring.boot

mybatis-spring-boot-starter

2.1.3

在配置文件中添加数据源相关信息,以及Mybatis的配置:

spring.datasource.url=jdbc:mysql://localhost:3306/security?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8

spring.datasource.username=root

spring.datasource.password=123456

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

mybatis.mapper-locations=classpath:mapper/*.xml

(三)认证与授权的实现

3.1 表结构设计

认证和授权在表设计上应该分在两个表内,一个表存储用户信息包括密码等,另一个表存储授权信息,还需要一个表建立用户和授权之间的关联,给出最终的表结构:

CREATE TABLE `roles` (

`id` int(4) NOT NULL,

`rolename` varchar(255) DEFAULT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `sysuser` (

`id` int(4) NOT NULL,

`username` varchar(255) NOT NULL,

`password` varchar(255) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `user_role` (

`id` int(4) NOT NULL,

`user_id` int(4) DEFAULT NULL,

`role_id` int(4) DEFAULT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

接下来是针对这三张表的实体类,Mapper接口以及xml文件,你可以不看代码,主要实现一个通过用户名查找用户以及相关权限的操作:

@Data

public class Roles {

private Integer id;

private String roleName;

}

@Data

public class SysUser {

private Integer id;

private String userName;

private String password;

private List roles;

}

Mapper接口:

public interface UserMapper {

public SysUser getUserByUserName(@Param("userName") String userName);

}

xml实现:

select sysuser.*,roles.rolename

from sysuser

LEFT JOIN user_role on sysuser.id= user_role.user_id

LEFT JOIN roles on user_role.role_id=roles.id

where username= #{userName}

3.2 认证过程

SpringSecurity的认证过程是这样的,首先通过用户名或者其他唯一的ID在数据库里找到这个用户,用户的密码以非对称加密的方式存储。取到用户后将前台传入的密码加密后和数据库中已经加密好的字段进行对比,从而通过认证。

上面这个过程中的第一步通过用户名找到用户的操作需要通过Service服务来实现,并且这个Service服务需要继承SpringSecurity中的UserDethttp://ailsService接口。这个接口返回一个SpringSecurity的User对象。

@Service

public class UserService implements UserDetailsService {

@Resource

private UserMapper userMapper;

//根据用户名找到对应的用户信息

@Override

public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {

SysUser sysUser = userMapper.getUserByUserName(s);

if (sysUser!=http://null){

List roles=new ArrayList<>();

sysUser.getRoles().stream().forEach(x->{

roles.add(new SimpleGrantedAuthority(x.getRoleName()));

});

return new User(sysUser.getUserName(),sysUser.getPassword(),roles);

}

throw new UsernameNotFoundException("用户未找到");

}

}

3.3 Security拦截配置

上面的步骤都完成后就开始配置Security了,写一个配置方法SecurityConfig,代码层面很简单,认证传入userService对象,会自动把数据库中取出的密码和前端传过来的密码进行对照。同时在userService中还传入了roles集合,在授权处Grajs给不同的页面附上不同的权限即可。

@EnableWebSecurity

public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired

private UserService userService;

//授权

@Override

protected void configure(HttpSecurity http) throws Exception {

//首页所有人都能访问,level页面只有有权限的人才能访问

http.authorizeRequests()

.antMatchers("/").permitAll()

.antMatchers("/level1/**").hasRole("vip1")

.antMatchers("/level2/**").hasRole("vip2")

.antMatchers("/level3/**").hasRole("vip3");

//没有权限默认跳到登陆页,默认会重定向到/login

http.formLogin();

}

//认证

@Override

protected void configure(AuthenticationManagerBuilder auth) throws Exception {

auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());

}

}

3.4 其他注意点

我在认证的时候使用的密码加密方式是BCryptPasswordEncoder,因此存入数据库中的密码也需要被加密,常用的方式就是在注册时通过同样的方式对密码进行加密存入数据库中:

String password="xxx";

BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();

String encode=bCryptPasswordEncoder.encode(password);

(四)总结

SpringSecurity很强大,除了这种方式之外,还支持集成JWT、Oauth2等等。后续我会继续更新,我是鱼仔,我们下期再见。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:混合app开发做微信支付(app实现微信支付)
下一篇:通软应用安全桌面要联网吗(通软应用安全桌面要联网吗怎么设置)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~