这篇文章主要介绍“怎么用SpringBoot+SpringSecurity实现基于真实数据的授权认证”,在日常操作中,相信很多人在怎么用SpringBoot+SpringSecurity实现基于真实数据的授权认证问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用SpringBoot+SpringSecurity实现基于真实数据的授权认证”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
在迁西等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都网站设计、做网站 网站设计制作按需求定制开发,公司网站建设,企业网站建设,成都品牌网站建设,全网营销推广,成都外贸网站制作,迁西网站建设费用合理。
Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架,Spring Security主要做两个事情,认证、授权。我之前写过一篇关于SpringSecurity的博客,但是当时只是介绍了基于mock数据的案例,本期就来介绍一下基于真实数据的认证授权实现。
为了更好的展示SpringSecurity,我们先搭建一个简单的web项目出来。引入thymeleaf依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-java8time</artifactId> </dependency>
新建一个登陆页,一个首页,然后几个不同等级的展示页面: login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登陆页</title> </head> <body> <div> <form> <h3>登陆页</h3> <input type="text" id="username" placeholder="username"> <input type="password" id="password" placeholder="password"> <button type="button">登陆</button> </form> </div> </body> </html>
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <div> <h3>首页</h3> <a href="/login">登陆</a> <div > <div > <h4>level1</h4> <a href="/level1/1">level-1-1</a> <hr> <a href="/level1/2">level-1-2</a> </div> <div > <h4>level2</h4> <a href="/level2/1">level-2-1</a> <hr> <a href="/level2/2">level-2-2</a> </div> <div > <h4>level3</h4> <a href="/level3/1">level-3-1</a> <hr> <a href="/level3/2">level-3-2</a> </div> </div> </div> </body> </html>
另外还有几个不同等级的页面
分别在body中写上自己对应的编号。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> level-1-1 </body> </html>
最后编写一个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相关依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.3</version> </dependency>
在配置文件中添加数据源相关信息,以及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
认证和授权在表设计上应该分在两个表内,一个表存储用户信息包括密码等,另一个表存储授权信息,还需要一个表建立用户和授权之间的关联,给出最终的表结构:
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> roles; }
Mapper接口:
public interface UserMapper { public SysUser getUserByUserName(@Param("userName") String userName); }
xml实现:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.javayz.springsecurity.mapper.UserMapper"> <resultMap id="userMap" type="com.javayz.springsecurity.entity.SysUser"> <id property="id" column="ID"/> <result property="userName" column="username"/> <result property="password" column="password"/> <collection property="roles" ofType="com.javayz.springsecurity.entity.Roles"> <result column="name" property="roleName"/> </collection> </resultMap> <select id="getUserByUserName" parameterType="String" resultMap="userMap"> 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} </select> </mapper>
SpringSecurity的认证过程是这样的,首先通过用户名或者其他唯一的ID在数据库里找到这个用户,用户的密码以非对称加密的方式存储。取到用户后将前台传入的密码加密后和数据库中已经加密好的字段进行对比,从而通过认证。
上面这个过程中的第一步通过用户名找到用户的操作需要通过Service服务来实现,并且这个Service服务需要继承SpringSecurity中的UserDetailsService接口。这个接口返回一个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!=null){ List<GrantedAuthority> 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("用户未找到"); } }
上面的步骤都完成后就开始配置Security了,写一个配置方法SecurityConfig,代码层面很简单,认证传入userService对象,会自动把数据库中取出的密码和前端传过来的密码进行对照。同时在userService中还传入了roles集合,在授权处给不同的页面附上不同的权限即可。
@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()); } }
我在认证的时候使用的密码加密方式是BCryptPasswordEncoder,因此存入数据库中的密码也需要被加密,常用的方式就是在注册时通过同样的方式对密码进行加密存入数据库中:
String password="xxx"; BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); String encode=bCryptPasswordEncoder.encode(password);
到此,关于“怎么用SpringBoot+SpringSecurity实现基于真实数据的授权认证”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!
当前名称:怎么用SpringBoot+SpringSecurity实现基于真实数据的授权认证
文章出自:https://www.cdcxhl.com/article44/ggjgee.html
成都网站建设公司_创新互联,为您提供用户体验、服务器托管、域名注册、网站改版、企业网站制作、外贸网站建设
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联