首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >SpringBoot+SpringSecurity+MySQL+JPA实现简单的权限认证和授权

SpringBoot+SpringSecurity+MySQL+JPA实现简单的权限认证和授权

作者头像
CodeWwang
发布2022-08-24 10:29:51
发布2022-08-24 10:29:51
9940
举报
文章被收录于专栏:CodeWwangCodeWwang

前言

  之前也想过,怎么样最为简单的实现权限的分离和用户的认证呢,学习了一下SpringSecurity,发现它能帮我们完成很多事情,目前来说只知道怎么去用,后面再仔细去研究。

思路

  想在SpringBoot中整合这些,先梳理一下思路。提供可以登录注册的2个表单,用户登录后可以进入首页(用户和管理员都能访问)。用户和管理员的权限不同,访问的页面也不同,用户注销后可以访问除首页登录注册页意外的页面会被拦截,自动跳到登录页。

前端

  知道大概思路开始设计前端页面了,使用SpringBoot索性就搭配thymeleaf模板了。

登录页:

代码语言:javascript
复制
<!DOCTYPE html> 
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org" 
 xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> 
<meta name="_csrf" th:content="${_csrf.token}"/> 
<meta name="_csrf_header" th:content="${_csrf.headerName}"/> 
<head> 
 <meta charset="UTF-8"> 
 <title>userLogin</title> 
</head> 
<body> 
<h1 align="center">UserLogin</h1> 
<div align="center"> 
 <div th:if="${param.error}"> 
        Invalid username and password. 
 </div> 
 <div th:if="${param.logout}"> 
        You have been logged out. 
 </div> 
 <form th:action="@{/login}" id="loginform" method="post"> 
 <div><label>用户名:<input name="username" placeholder="请输入用户名"/></label></div> 
 <div><label>密码:<input name="password" placeholder="请输入密码"/></label></div> 
 <div><label><input type="text" name="verification" id="verification" class="form-control" placeholder="请输入验证码"> 
 <img id="imgVerify" src="" onclick="getVerify();" 
 alt="点击更换验证码"/><a href="#" onclick="getVerify();" rel="nofollow">看不清,换一张</a></label></div> 
 <input type="button" onclick="checkCode()" value="提交"/> 
 </form> 
</div> 
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script> 
<script type="text/javascript"> 
    $(document.body).ready(function () { 
 var token = $("meta[name='_csrf']").attr("content"); 
 var header = $("meta[name='_csrf_header']").attr("content"); 
        $(document).ajaxSend(function (e, xhr, options) { 
            xhr.setRequestHeader(header, token); 
 }); 
 //首次获取验证码 
        $("#imgVerify").attr("src", "/getVerify?" + Math.random()); 
 }); 
 //获取验证码 
 function getVerify() { 
 var src1 = document.getElementById('imgVerify') 
        src1.src = "/getVerify?" + Math.random(); 
 } 
</script> 
<script type="text/javascript"> 
 function checkCode() { 
 var checkCode = $("#verification").val().toLowerCase(); 
        $.post("/checkCode", {'checkCode': checkCode}, function (result) { 
 if (result.success == "true") { 
                $("#loginform").submit(); 
 } else { 
                alert(result.errorInfo); 
 } 
 }, "json"); 
 } 
</script> 
</body> 
</html> 

注册页:

代码语言:javascript
复制
<!DOCTYPE html> 
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org" 
 xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> 
<head> 
 <meta charset="UTF-8"> 
 <title>userRegister</title> 
</head> 
<body> 
<h1 align="center">UserRegister</h1> 
<div align="center"> 
 <form th:action="@{/register}" method="post"> 
 <table> 
 <tr> 
                用户名:<input name="username" placeholder="请输入用户名"/><br> 
 <div id="udiv" style="color: crimson"></div> 
                密 码:<input name="password" placeholder="请输入密码"/><br> 
 <div id="pdiv" style="color: crimson"></div> 
                手机号:<input name="tel" placeholder="请输入手机号码"/><br> 
 <div id="tdiv" style="color: crimson"></div> 
                角色:<select name="role"> 
 <option value="ADMIN,USER">管理员</option> 
 <option value="USER">用户</option> 
 </select> 
 <input type="submit" value="提 交"/> 
 </tr> 
 </table> 
 </form> 
</div> 
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script> 
<script type="text/javascript"> 
 //校验用户名 
    $("input[name='username']").blur(function () { //失去焦点 
 var namestr = $(this).val(); 
 var regstr = /^[a-z0-9_-]{3,6}$/; 
 if (!regstr.test(namestr)) { 
            $("#udiv").show().text("请输3到6位用户名!"); 
            $("#udiv").fadeOut(3000); 
 return false; 
 } 
 return true; 
 }); 
 //校验密码 
    $("input[name='password']").blur(function () { //失去焦点 
 var namestr = $(this).val(); 
 var regstr = /^[a-z0-9_-]{3,6}$/; 
 if (!regstr.test(namestr)) { 
            $("#pdiv").show().text("请输3到6位密码!"); 
            $("#pdiv").fadeOut(3000); 
 return false; 
 } 
 return true; 
 }); 
 //校验手机号码 
    $("input[name='tel']").blur(function () { //失去焦点 
 var telstr = $(this).val(); 
 var regstr = /1\d{10}/; 
 if (!regstr.test(telstr)) { 
            $("#tdiv").show().text("请输入正确的11位手机号格式!"); 
            $("#tdiv").fadeOut(3000); 
 return false; 
 } 
 return true; 
 }); 
</script> 
</body> 
</html> 

后端

SecurityConfig

代码语言:javascript
复制
package cn.seczone.demo.config.security; 
import cn.seczone.demo.service.UserService; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 
import org.springframework.security.config.annotation.web.builders.HttpSecurity; 
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 
import org.springframework.security.crypto.password.PasswordEncoder; 
@Configuration 
@EnableWebSecurity 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 
 @Autowired 
 UserService userService; 
 //认证 
 @Override 
 protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder()); 
 } 
 //授权 
 @Override 
 protected void configure(HttpSecurity http) throws Exception { 
 /*http.csrf().disable()*/ 
               http 
 .authorizeRequests() 
 .antMatchers("/favicon.ico","/css/**","/common/**","/js/**","/images/**","/login","/register","/login-error","/home/**","/").permitAll() 
 .antMatchers("/admin/**").hasRole("ADMIN") 
 .antMatchers("/user/**").hasRole("USER") 
 .antMatchers("/checkCode").permitAll() 
 .antMatchers("/getVerify").permitAll() 
 .anyRequest().authenticated() 
 .and() 
 .formLogin() 
 .loginPage("/home/toLogin") 
 .loginProcessingUrl("/login") 
 .successForwardUrl("/home/hello") 
 .failureForwardUrl("/home/error") 
 .permitAll() 
 .and() 
 .logout() 
 .permitAll(); 
 } 
 @Bean 
 PasswordEncoder passwordEncoder(){ 
 return new BCryptPasswordEncoder(); 
 } 
} 

UserService实现UserDetailService

代码语言:javascript
复制
package cn.seczone.demo.service; 
import cn.seczone.demo.dao.UserDao; 
import cn.seczone.demo.model.User; 
import org.junit.Test; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.security.core.userdetails.UserDetails; 
import org.springframework.security.core.userdetails.UserDetailsService; 
import org.springframework.security.core.userdetails.UsernameNotFoundException; 
import org.springframework.stereotype.Service; 
@Service 
public class UserService implements UserDetailsService { 
 @Autowired 
 private UserDao userDao; 
 @Override 
 public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException { 
 User user = userDao.findUserByUsername(name); 
 if(user==null){ 
 throw new UsernameNotFoundException("用户名不存在"); 
 } 
 return  user; 
 } 
} 

User实体要实现UserDetails接口:

代码语言:javascript
复制
 /** 
     * @description: 账户是否过期 
     * @return 
     */ 
 @Override 
 public boolean isAccountNonExpired() { 
 return true; 
 } 
 /** 
     * @description: 账户是否被冻结 
     * @return 
     */ 
 @Override 
 public boolean isAccountNonLocked() { 
 return true; 
 } 
 /** 
     * @description: 账户密码是否过期(对于高密码安全性场景) 
     * @return 
     */ 
 @Override 
 public boolean isCredentialsNonExpired() { 
 return true; 
 } 
 /** 
     * @description: 账号是否可用 
     * @return 
     */ 
 @Override 
 public boolean isEnabled() { 
 return true; 
 } 
 @Override 
 public Collection<? extends GrantedAuthority> getAuthorities() { 
 List<SimpleGrantedAuthority> authorities = new ArrayList<>(); 
 String[] roles = this.getRole().split(","); 
 for (String role: roles 
 ) { 
            authorities.add(new SimpleGrantedAuthority("ROLE_"+role)); 
 } 
 return authorities; 
 } 

这样基本的Security权限管理就搭建好了!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/12/28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 思路
  • 前端
  • 后端
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档