项目pom文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.13</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>logindemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>logindemo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<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.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.9</version>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>layui</artifactId>
<version>2.7.6</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.21</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.mysql</groupId>-->
<!-- <artifactId>mysql-connector-j</artifactId>-->
<!-- <scope>runtime</scope>-->
<!-- </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>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.github.taoyua</groupId>
<artifactId>logindemo</artifactId>
<version>0.0.1-RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
</plugins>
</build>
</project>
项目config配置:
SecrityConfig
import com.example.logindemo.service.LoginDetailsService;
import com.example.logindemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
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.builders.WebSecurity;
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;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
MySecritySuccessHandler mySecritySuccessHandler;
@Autowired
MySecrityFailureHandler mySecrityFailureHandler;
@Autowired
LoginDetailsService userDetailsService;
@Autowired
MySecrityLogoutHandler mySecrityLogoutHandler;
@Autowired
UserService userService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.headers().frameOptions().disable()
.and().formLogin()
.loginPage("/login")
.loginProcessingUrl("/form")
.successHandler(mySecritySuccessHandler)
.failureHandler(mySecrityFailureHandler)
.and().authorizeRequests().antMatchers( "**/static/**","**/templates/**","/login")
.permitAll()
.anyRequest().authenticated();
/**
* 退出处理,logoutSuccessurl退出成功跳转登录
*/
http.logout().logoutUrl("/signout").deleteCookies("JSESSIONID")//清除cookies
.logoutSuccessHandler(mySecrityLogoutHandler);
// .logoutSuccessUrl("/login").invalidateHttpSession(true);
}
/**
* 忽略静态资源访问控制
*/
@Override
public void configure(WebSecurity web) throws Exception {
//解决静态资源被拦截的问题
web.ignoring().antMatchers("/css/**","/api/**","/images/**","/page/**",
"/lib/**","/layui/**","/js/**","/*.js","/*.css","/*.png");
}
/**
* 登录逻辑实现,获取数据库账号密码
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());
}
/**
* 内存处理用户名及密码
*/
// @Autowired
// public void configureGlobal(AuthenticationManagerBuilder auth)throws Exception{
// auth.inMemoryAuthentication()
// .passwordEncoder(new BCryptPasswordEncoder())
// .withUser("admin")
// .password(new BCryptPasswordEncoder().encode("123456"))
// .roles("USER");
// }
// 密码加密
// public static void main(String[] args) {
// BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
// boolean matches = bCryptPasswordEncoder.matches( "123456","$2a$10$.y6yRGGU6uXyrq0Ftmdb9.WSZTZPZJmnoisz0IxaiRqvjPKUcywjq");
// System.out.println(matches);
// System.out.println(new BCryptPasswordEncoder().encode("123456"));
}
MySecritySuccessHandler:
import com.alibaba.fastjson2.JSON;
import com.example.logindemo.entity.Result;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class MySecritySuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
httpServletResponse.setContentType("application/json;charset=utf-8");
Result result = new Result();
result.setRespcode("0000");
result.setRespmsg("登录成功");
String res = JSON.toJSONString(result);
httpServletResponse.getWriter().print(res);
}
}
MySecrityFailureHandler:
import com.alibaba.fastjson2.JSON;
import com.example.logindemo.entity.Result;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class MySecrityFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
httpServletResponse.setContentType("application/json;charset=utf-8");
Result result = new Result();
result.setRespcode("1111");
result.setRespmsg("登录失败!");
String res = JSON.toJSONString(result);
httpServletResponse.getWriter().print(res);
}
}
MySecrityLogoutHandler:
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class MySecrityLogoutHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
httpServletResponse.sendRedirect(httpServletRequest.getContextPath()+"/login");//重定向到login
}
}
控制类controller如下:
LoginController:
import com.example.logindemo.service.LoginDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class LoginController {
@Autowired
LoginDetailsService loginDetailsService;
@RequestMapping("/login")
public String login1(){
return "login";
}
// @PostMapping("/login")
// public Result login1(String username, String password, HttpServletRequest request){
// return loginDetailsService.loadUserByUsername(username);
//
// }
@RequestMapping("/signout")
public String signout(){
return "login";
}
@RequestMapping("/index")
public String index(){
return "index";
}
@RequestMapping("/main")
public String main(){
return "main";
}
}
UserController:
import com.alibaba.fastjson2.JSONObject;
import com.example.logindemo.entity.User;
import com.example.logindemo.service.MenuService;
import com.example.logindemo.service.RoleService;
import com.example.logindemo.service.UserService;
import com.example.logindemo.utils.CommonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Map;
@Slf4j
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
RoleService roleService;
@Autowired
UserService userService;
@Autowired
MenuService menuservice;
@GetMapping("/menus")
@ResponseBody
public Map<String, Object> menus() {
String loginUsername = CommonUtils.getLoginUser();
User loginUser = userService.findUserByusername(loginUsername);
JSONObject initjson=new JSONObject(menuservice.menu(loginUser.getId()));
return initjson;
}
}
实体类entity:
Menu:
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.util.List;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Menu {
private Long id;
private Long pid;
private String title;
private String icon;
private String href;
// private String target;
private List<Menu> children;
}
Role:
import lombok.Data;
@Data
public class Role {
private long id;
private String name;
//角色编码
private String sn;
//角色描述
private String desc;
}
User:
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
@Data
public class User {
private Long id;
private String username;
private String password;
private String tel;
private String sex;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private String createTime;
}
Result类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {
private String respcode;
private String respmsg;
}
mapper类如下:
MenuMapper:
import com.example.logindemo.entity.Menu;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface MenuMapper {
@Select("SELECT sr.id,sr.pid pid,sr.title,sr.icon,sr.href\n" +
"FROM treemenu sr where STATUS = 1 ORDER BY sort")
List<Menu> ListPermissionByuserid(long userid);
@Select("SELECT sr.id,sr.pid pid,sr.title,sr.icon,sr.href,sr.target FROM treemenu sr")
List<Menu> listMenuByRoleid(long id);
// @Select("SELECT sr.id,sr.pid pid,sr.title,sr.icon,sr.href,sr.target\n" +
// "FROM sys_resources sr\n" +
// "join role_treemenu st on st.menu_id=sr.id\n" +
// "and st.role_id=#{id}")
// List<MenuVo> listMenuByRoleid(long id);
}
RoleMapper:
import com.example.logindemo.entity.Role;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface RoleMapper {
@Select("SELECT r.*\n" +
"from role r\n" +
"JOIN t_user_role u on r.id=u.roleid\n" +
"where u.userid=#{userid}")
List<Role> listRoleByuserid(long userid);//根据userID,查询该用户的角色
}
UserMapper:
import com.example.logindemo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface UserMapper {
@Select("select *from admin where username=#{username}")
User findUserByusername(String username);
}
service中的Impl实现类:
LoginDetailsService
import com.example.logindemo.entity.Role;
import com.example.logindemo.entity.User;
import com.example.logindemo.service.RoleService;
import com.example.logindemo.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Component
public class LoginDetailsService implements org.springframework.security.core.userdetails.UserDetailsService {
@Autowired
UserService userService;
@Autowired
RoleService roleService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//获取数据库用户
User user= userService.findUserByusername(username);
if(user==null){
throw new UsernameNotFoundException("用户不存在");
}else{
// log.info("查到用户");
Set authorities=new HashSet<>();
// List<Role> roles = roleService.listRoleByuserid(user.getId());
// for(Role role:roles) {
// authorities.add(new SimpleGrantedAuthority("ROLE_"+role.getName()));
// }
authorities.add(new SimpleGrantedAuthority("Role_管理员"));
return new org.springframework.security.core.userdetails.User(user.getUsername(),user.getPassword(),
true,true,true,true,authorities);
}
}
}
MenuService:
import com.example.logindemo.entity.Menu;
import com.example.logindemo.entity.Role;
import com.example.logindemo.mapper.MenuMapper;
import com.example.logindemo.utils.TreeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
@Service
public class MenuService {
@Resource
MenuMapper menuMapper;
@Resource
RoleService roleService;
public Map<String, Object> menu(Long userid) {
/**
* 根据用户id获取用户所有角色
*/
//
// List<Role> roleidList = roleService.listRoleByuserid(userid);
// /**
// * 遍历所有角色,获取list菜单
// */
// Set<Menu> menuSet=new HashSet<>();
// for(Role role:roleidList){
// List<Menu> sysMenuList = menuMapper.listMenuByRoleid(role.getId());
// for(Menu menu :sysMenuList){
// menuSet.add(menu);
// }
//
// }
// List<Menu> sysmenuList=new ArrayList<>(menuSet);
//将菜单转为权限树
List<Menu> menuInfo=menuMapper.ListPermissionByuserid(userid);
List<Menu> menuTree = new ArrayList<>();
menuTree= TreeUtil.toTree(menuInfo, 0L);
Map<String, Object> map = new HashMap<>();
map.put("data", menuTree);
return map;
}
}
RoleService:
import com.example.logindemo.entity.Role;
import com.example.logindemo.mapper.RoleMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class RoleService {
@Resource
private RoleMapper roleMapper;
public List<Role> listRoleByuserid(long userid) {
List<Role> roles = roleMapper.listRoleByuserid(userid);
return roles;
}
}
UserService:
import com.example.logindemo.entity.User;
import com.example.logindemo.mapper.UserMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class UserService {
@Resource
UserMapper usermapping;
public User findUserByusername(String username) {
return usermapping.findUserByusername(username);
}
}
utils工具类:
CommonUtils:
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
public class CommonUtils {
public static String getLoginUser(){
//获取登录认证对象
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
//得到认证的主体(登录用户)
if(authentication!=null) {
return authentication.getName();
}
return null;
}
}
TreeUtil:
import com.example.logindemo.entity.Menu;
import java.util.ArrayList;
import java.util.List;
public class TreeUtil {
public static List<Menu> toTree(List<Menu> treeList, Long pid) {
List<Menu> retList = new ArrayList<Menu>();
for (Menu parent : treeList) {
if (pid.equals(parent.getPid())) {
retList.add(findChildren(parent, treeList));
}
}
return retList;
}
private static Menu findChildren(Menu parent, List<Menu> treeList) {
for (Menu child : treeList) {
if (parent.getId().equals(child.getPid())) {
if (parent.getChildren() == null) {
parent.setChildren(new ArrayList<>());
}
parent.getChildren().add(findChildren(child, treeList));
}
}
return parent;
}
}
application.properties
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#云上
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://rm-bp1l57prt0jm1g81x.mysql.rds.aliyuncs.com:3306/manage_system?characterEncoding=utf8
spring.datasource.username=yt
spring.datasource.password=Yt@123456
spring.web.resources.static-locations=classpath:/static/,/templates/
spring.thymeleaf.cache=false