SpringBoot +SpringSecurity+mysql 实现用户数据权限管理

通用用户数据权限sql建库 和初始化脚本:

/*
 Navicat MySQL Data Transfer

 Source Server         : 192.168.1.73
 Source Server Type    : MySQL
 Source Server Version : 80015
 Source Host           : 192.168.1.73:3306
 Source Schema         : boot-security

 Target Server Type    : MySQL
 Target Server Version : 80015
 File Encoding         : 65001

 Date: 15/07/2019 16:40:44
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for u_permission
-- ----------------------------
DROP TABLE IF EXISTS `u_permission`;
CREATE TABLE `u_permission`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `url` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'url地址',
  `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'url描述',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 21 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of u_permission
-- ----------------------------
INSERT INTO `u_permission` VALUES (1, 'userInfo/userList', '用户管理');
INSERT INTO `u_permission` VALUES (2, 'userInfo/userAdd', '用户添加');
INSERT INTO `u_permission` VALUES (3, 'userInfo/userDel', '用户删除');

-- ----------------------------
-- Table structure for u_role
-- ----------------------------
DROP TABLE IF EXISTS `u_role`;
CREATE TABLE `u_role`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '角色名称',
  `type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '角色类型',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of u_role
-- ----------------------------
INSERT INTO `u_role` VALUES (1, 'admin', '1');
INSERT INTO `u_role` VALUES (2, 'user', '2');

-- ----------------------------
-- Table structure for u_role_permission
-- ----------------------------
DROP TABLE IF EXISTS `u_role_permission`;
CREATE TABLE `u_role_permission`  (
  `rid` bigint(20) NULL DEFAULT NULL COMMENT '角色ID',
  `pid` bigint(20) NULL DEFAULT NULL COMMENT '权限ID',
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of u_role_permission
-- ----------------------------
INSERT INTO `u_role_permission` VALUES (1, 1, 1);
INSERT INTO `u_role_permission` VALUES (1, 2, 2);
INSERT INTO `u_role_permission` VALUES (1, 3, 3);
INSERT INTO `u_role_permission` VALUES (2, 1, 4);
INSERT INTO `u_role_permission` VALUES (2, 2, 5);
INSERT INTO `u_role_permission` VALUES (2, 3, 6);

-- ----------------------------
-- Table structure for u_user
-- ----------------------------
DROP TABLE IF EXISTS `u_user`;
CREATE TABLE `u_user`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `nickname` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户昵称',
  `email` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '邮箱|登录帐号',
  `pswd` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '密码',
  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  `last_login_time` datetime(0) NULL DEFAULT NULL COMMENT '最后登录时间',
  `status` bigint(1) NULL DEFAULT 1 COMMENT '1:有效,0:禁止登录',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of u_user
-- ----------------------------
INSERT INTO `u_user` VALUES (1, 'admin', 'admin@163.com', 'C4CA4238A0B923820DCC509A6F75849B', '2019-04-27 22:44:44', NULL, 1);

-- ----------------------------
-- Table structure for u_user_role
-- ----------------------------
DROP TABLE IF EXISTS `u_user_role`;
CREATE TABLE `u_user_role`  (
  `uid` bigint(20) NULL DEFAULT NULL COMMENT '用户ID',
  `rid` bigint(20) NULL DEFAULT NULL COMMENT '角色ID',
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of u_user_role
-- ----------------------------
INSERT INTO `u_user_role` VALUES (1, 2, 1);

SET FOREIGN_KEY_CHECKS = 1;

项目截图:

1、springsecurity 配置类:SecurityConfiguration

只要使用spring security都要有这样一个配置类(如果是类配置的话),继承WebSecurityConfigurerAdapter 主要实现两个方法configure(AuthenticationManagerBuilder auth)和 configure(HttpSecurity http)

AuthenticationManagerBuilder: 主要配置身份认证来源,也就是用户及其角色。

HttpSecurity 主要配置路径:也就是资源的访问权限(是否需要认证,需要什么角色等)。

自定义securityConfiguration:SpringSecurityConfig

package com.zzg.security.config;

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.method.configuration.EnableGlobalMethodSecurity;
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.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import com.zzg.security.provider.SpringSecurityProvider;

/**
 * spring-security 配置文件
 * @author zzg
 *
 */

@Configuration
@EnableWebSecurity //开启Spring Security的功能
@EnableGlobalMethodSecurity(prePostEnabled=true)//开启注解控制权限
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
	
	 /**
     * עSpringSecurityProvider
     */
    @Autowired
    private SpringSecurityProvider provider;
    
    /**
     *AuthenticationSuccessHandler
     */
    @Autowired
    private AuthenticationSuccessHandler securityAuthenticationSuccessHandler;
    /**
     *  AuthenticationFailureHandler
     */
    @Autowired
    private AuthenticationFailureHandler securityAuthenticationFailHandler;

    /**
	 * 定义需要过滤的静态资源(等价于HttpSecurity的permitAll)
	 */
	@Override
	public void configure(WebSecurity webSecurity) throws Exception {
		webSecurity.ignoring().antMatchers("static/css/**");
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// TODO Auto-generated method stub
		http.authorizeRequests()
        .antMatchers("/login").permitAll() // 不需要权限路径
        .anyRequest().authenticated()      
        .and()
        .formLogin()
        .loginPage("/login")    // 登入页面
        .successHandler(securityAuthenticationSuccessHandler)  //自定义成功处理器
        .failureHandler(securityAuthenticationFailHandler)     //自定义失败处理器
        .permitAll()
        .and()
        .logout();
		
	}



	@Override
	protected void configure(AuthenticationManagerBuilder builder) throws Exception {
		// 自定义身份验证提供者
		builder.authenticationProvider(provider);
	}
	
	
	

}

2、springsecurity 认证接口:AuthenticationProvider

spring security实现自定义认证,需要实现AuthenticationProvider接口:主要实现方法authenticate(Authentication authentication)

自定义AuthenticationProvider:SpringSecurityProvider

package com.zzg.security.provider;

import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import com.zzg.security.userservice.AuthUserDetails;
import com.zzg.security.userservice.CustomUserService;

/**
 *自定义身份验证提供者
 * 
 * @author zzg
 *
 */
@Component
public class SpringSecurityProvider implements AuthenticationProvider {

	@Autowired
	private CustomUserService userDetailService;

	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		// TODO Auto-generated method stub
		String userName = authentication.getName();
		String password = (String) authentication.getCredentials();

	    // 查询用户权限信息
		AuthUserDetails userInfo = (AuthUserDetails) userDetailService.loadUserByUsername(userName); 
		if (userInfo == null) {
			throw new UsernameNotFoundException("");
		}

		// 密码判断
		String encodePwd = DigestUtils.md5Hex(password).toUpperCase();
		if (!userInfo.getPassword().equals(encodePwd)) {
			throw new BadCredentialsException("");
		}

		return new UsernamePasswordAuthenticationToken(userInfo, userInfo.getPassword(),
				userInfo.getAuthorities());
	}

	@Override
	public boolean supports(Class<?> authentication) {
		// TODO Auto-generated method stub
		return UsernamePasswordAuthenticationToken.class.equals(authentication);
	}

}

2、springsecurity 用户详情信息接口:UserDetailsService

spring security实现自定义用户详情信息,需要实现UserDetailsService接口:主要实现方法loadUserByUsername(String username)

自定义UserDetailsService:CustomUserService

package com.zzg.security.userservice;

import java.util.List;
import java.util.stream.Collectors;

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.Component;

import com.zzg.entity.Permission;
import com.zzg.entity.Role;
import com.zzg.entity.RolePermission;
import com.zzg.entity.User;
import com.zzg.entity.UserRole;
import com.zzg.service.PermissionService;
import com.zzg.service.RolePermissionService;
import com.zzg.service.RoleService;
import com.zzg.service.UserRoleService;
import com.zzg.service.UserService;
/**
 * 自定义用户查询服务
 * @author zzg
 *
 */

@Component
public class CustomUserService implements UserDetailsService {
	@Autowired
	private UserService userService;
	@Autowired
	private UserRoleService userRoleService;
	@Autowired
	private RoleService roleService;
	@Autowired
	private RolePermissionService rolePermissionService;
	@Autowired
	private PermissionService permissionService;
	

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		// TODO Auto-generated method stub
		User user = userService.findByUserName(username);
		if(user == null){
			 throw new UsernameNotFoundException("");
		}
		List<UserRole> list = userRoleService.findByUid(user.getId());
		List<Long> rIds = list.stream().map(UserRole::getRid).collect(Collectors.toList());
		
		List<Role> roles = roleService.findByIds(rIds);
		List<Long> roleIds = roles.stream().map(Role::getId).collect(Collectors.toList());
		
		List<RolePermission> rolePermissions = rolePermissionService.findByRids(roleIds);
		List<Long> pIds = rolePermissions.stream().map(RolePermission::getPid).collect(Collectors.toList());
		
		List<Permission> permissions = permissionService.findByIds(pIds);
		
		AuthUserDetails authUserDetails = new AuthUserDetails(user.getNickname(),user.getPswd(),roles,permissions);
		
		return authUserDetails;
	}

}

3、springsecurity 用户信息拓展:UserDetails

spring security 拓展用户信息,继承UserDetails类,主要方法:Collection<? extends GrantedAuthority> getAuthorities() 构建用户权限信息。

自定义UserDetails:AuthUserDetails

package com.zzg.security.userservice;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import com.zzg.entity.Permission;
import com.zzg.entity.Role;

@SuppressWarnings("serial")
public class AuthUserDetails implements UserDetails {
	
	private String nickname;

    private String pswd;
    
   
    private List<Role> roles;
  
    private List<Permission> permission;
    
  
	public String getNickname() {
		return nickname;
	}

	public void setNickname(String nickname) {
		this.nickname = nickname;
	}

	public String getPswd() {
		return pswd;
	}

	public void setPswd(String pswd) {
		this.pswd = pswd;
	}

	public List<Role> getRoles() {
		return roles;
	}

	public void setRoles(List<Role> roles) {
		this.roles = roles;
	}

	public List<Permission> getPermission() {
		return permission;
	}

	public void setPermission(List<Permission> permission) {
		this.permission = permission;
	}
	
	
	public AuthUserDetails(String nickname, String pswd, List<Role> roles, List<Permission> permission) {
		super();
		this.nickname = nickname;
		this.pswd = pswd;
		this.roles = roles;
		this.permission = permission;
	}
	
	public AuthUserDetails(){
		this.nickname = "NA";
		this.pswd = "NA";
		this.roles = Collections.EMPTY_LIST;
		this.permission = Collections.EMPTY_LIST;
	}

	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		// 基于用户角色名称构建权限信息
		 List<GrantedAuthority> auths = new ArrayList<>();
		 List<Role> roles = this.getRoles();
		 for (Role role : roles) {
	            auths.add(new SimpleGrantedAuthority(role.getName()));
	        }
		 
		return auths;
	}

	/**
	 *
	 */
	@Override
	public String getPassword() {
		// TODO Auto-generated method stub
		return this.pswd;
	}

	/**
	 * 
	 */
	@Override
	public String getUsername() {
		// TODO Auto-generated method stub
		return this.nickname;
	}
 
	/**
	 * 
	 */
	@Override
	public boolean isAccountNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}

	/**
	 * 
	 */
	@Override
	public boolean isAccountNonLocked() {
		// TODO Auto-generated method stub
		return true;
	}

	/**
	 * 
	 */
	@Override
	public boolean isCredentialsNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}

	/**
	 * 
	 */
	@Override
	public boolean isEnabled() {
		// TODO Auto-generated method stub
		return true;
	}

}

4、自定义springsecurity 登入成功处理的Handler:一般需要实现AuthenticationSuccessHandler 接口,覆写onAuthenticationSuccess(HttpServletRequest request,HttpServletResponse response, Authentication authentication) throws IOException, ServletException 方法

自定义AuthenticationSuccessHandler:SecurityAuthenticationSuccessHandler

package com.zzg.security.handler;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import com.zzg.redis.util.RedisUtil;

/**
 * 用户登入成功
 * @author zzg
 *
 */
@Component("securityAuthenticationSuccessHandler")
public class SecurityAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
	@Autowired
	private RedisUtil redisUtil;

	@Override
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
			Authentication authentication) throws ServletException, IOException {
		// 用户登入成功,补充相关业务逻辑
         new DefaultRedirectStrategy().sendRedirect(request, response, "/defaults");
	}

	
}

5、自定义springsecurity 登入失败处理的Handler:一般需要实现AuthenticationFailureHandler接口,覆写onAuthenticationFailure(HttpServletRequest request,HttpServletResponse response, AuthenticationException exception)
throws IOException, ServletException 方法

package com.zzg.security.handler;

import java.io.IOException;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;

/**
 * 用户登入失败
 * @author zzg
 *
 */
@Component("securityAuthenticationFailHandler")
public class SecurityAuthenticationFailHandler extends SimpleUrlAuthenticationFailureHandler {
	
	@Override
	public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
			AuthenticationException exception) throws IOException, ServletException {
        String redirectUrl = "/login?message=" + URLEncoder.encode(exception.getMessage(),"UTF-8");
        new DefaultRedirectStrategy().sendRedirect(request, response, redirectUrl);
	}
    
    
}

6、自定义权限不足处理器,实现AccessDeniedHandler接口,覆写handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) 方法

package com.zzg.security.access.denied;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;

import com.zzg.security.util.HttpUtils;
/**
 * 自定义权限不足处理器
 * @author zzg
 *
 */
@Component
public class SpringSecurityAccessDeniedHandler implements AccessDeniedHandler {

	@Override
	public void handle(HttpServletRequest request, HttpServletResponse response,
			AccessDeniedException accessDeniedException) throws IOException, ServletException {
		// TODO Auto-generated method stub
		boolean isAjax = HttpUtils.isAjaxRequest(request);
		if(isAjax){
			// 前端提示授权信息不足
			response.setContentType("text/html;charset=UTF-8");
			PrintWriter out = response.getWriter();
			out.println("权限不足");
			
		} else {
			// 后端直接跳转至权限的错误页面
			new DefaultRedirectStrategy().sendRedirect(request, response, "/errors");
		}
		
	}
	

}

至此已经完成基于数据库存储的Spring Security权限控制的核心配置。

以下的代码主要是controller、springmvc 配置和工具类代码代码:

Http 工具类:

package com.zzg.security.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

import org.springframework.http.HttpHeaders;

public class HttpUtils {
	/**
	 * 获取请求Body
	 *
	 * @param request
	 * @return
	 */
	public static String getBodyString(ServletRequest request) {
		StringBuilder sb = new StringBuilder();
		InputStream inputStream = null;
		BufferedReader reader = null;
		try {
			inputStream = request.getInputStream();
			reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
			String line = "";
			while ((line = reader.readLine()) != null) {
				sb.append(line);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return sb.toString();
	}

	/**
	 * 从request获取登录的IP
	 */
	public static String getIpAddress(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_CLIENT_IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("X-Real-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}

	/**
	 * 判断是否为ajax请求
	 */
	public static boolean isAjaxRequest(HttpServletRequest request) {
		if (request.getHeader(HttpHeaders.ACCEPT) != null
				&& request.getHeader(HttpHeaders.ACCEPT).indexOf("application/json") > -1
				|| (request.getHeader("X-Requested-With") != null
						&& request.getHeader("X-Requested-With").equalsIgnoreCase("XMLHttpRequest"))) {
			return true;
		}
		return false;
	}
}

springMVC 配置:

package com.zzg.springmvc.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 访问路径配置类 可以理解成做简单访问过滤的,转发到相应的视图页面
 * 
 * @author Veiking
 */
@Configuration
public class SpringMvcConfig implements WebMvcConfigurer {

	@Override
	public void addViewControllers(ViewControllerRegistry registry) {
		// TODO Auto-generated method stub
		registry.addViewController("/login").setViewName("login.html");
		registry.addViewController("/").setViewName("index.html");
		registry.addViewController("/index").setViewName("index.html");
	}

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		// TODO Auto-generated method stub
		registry.addResourceHandler("/**").addResourceLocations("classpath:/static/**");
	}
	
	

}
package com.zzg.controller;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class LoginController {
	
	/**
	 * 鉴权用户是否拥有指定权限
	 * @param model
	 * @param tt
	 * @return
	 */
	@RequestMapping("/admin")
	@PreAuthorize("hasAuthority('admin')")
	public String admin(Model model, String tt) {
		return "admin";
	}
	
	@RequestMapping("/hello")
	public String hello(Model model, String tt) {
		return "hello";
	}
	/**
	 * 登入成功跳转页面
	 * @param model
	 * @param tt
	 * @return
	 */
	@RequestMapping("/defaults")
	public String defaults(Model model, String tt) {
		return "defaults";
	}
	
	/**
	 * 权限不足跳转页面
	 * @param model
	 * @param tt
	 * @return
	 */
	@RequestMapping("/errors")
	public String errors(Model model, String tt) {
		return "errors";
	}
	
	
	

}

静态页面:

admin.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:th="http://www.thymeleaf.org"
	xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
<title>ADMIN</title>
<link rel="stylesheet" th:href="@{static/css/bootstrap.min.css}"/>
<style type="text/css">
body { padding: 40px; }
</style>
</head>
<body>
	<h1>ADMIN</h1>
	<br/>你好:<a sec:authentication="name"></a>
	<p>
		<a th:href="@{/index}"> INDEX</a>
		<a th:href="@{/admin}"> | ADMIN</a>
		<a th:href="@{/hello}"> | HELLO</a>
		<br/><hr/>
        <form th:action="@{/logout}" method="post">
            <input type="submit" class="btn btn-primary" value="注销"/>
        </form>
	</p>
</body>
</html>

defaults.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:th="http://www.thymeleaf.org"
	xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
<title>成功默认登入页面</title>
<link rel="stylesheet" th:href="@{static/css/bootstrap.min.css}"/>
<style type="text/css">
body { padding: 40px; }
</style>
</head>
<body>
	<h1>成功默认登入页面</h1>
	<br/>成功默认登入页面:<a sec:authentication="name"></a>
	<p>
		<a th:href="@{/index}"> INDEX</a>
		<a th:href="@{/admin}"> | ADMIN</a>
		<a th:href="@{/hello}"> | HELLO</a>
		<br/><hr/>
        <form th:action="@{/logout}" method="post">
            <input type="submit" class="btn btn-primary" value="注销"/>
        </form>
	</p>
</body>
</html>

error.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:th="http://www.thymeleaf.org"
	xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
<title>方法权限不足提示页面</title>
<link rel="stylesheet" th:href="@{static/css/bootstrap.min.css}"/>
<style type="text/css">
body { padding: 40px; }
</style>
</head>
<body>
	<h1>方法权限不足提示页面</h1>
	<br/>方法权限不足提示页面:<a sec:authentication="name"></a>
	<p>
		<a th:href="@{/index}"> INDEX</a>
		<a th:href="@{/admin}"> | ADMIN</a>
		<a th:href="@{/hello}"> | HELLO</a>
		<br/><hr/>
        <form th:action="@{/logout}" method="post">
            <input type="submit" class="btn btn-primary" value="注销"/>
        </form>
	</p>
</body>
</html>

hello.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"	
	xmlns:th="http://www.thymeleaf.org"
	xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
<meta content="text/html;charset=UTF-8"/>
<title>HELLO</title>
<link rel="stylesheet" th:href="@{static/css/bootstrap.min.css}"/>
<style type="text/css">
body { padding: 40px; }
</style>
</head>
<body>
	<h1>HELLO</h1>
	<br/>你好:<a sec:authentication="name"></a>
	<p>
		<a sec:authorize="hasAuthority('admin')" th:href="@{/index}"> INDEX</a>
		<a sec:authorize="hasAuthority('admin')" th:href="@{/admin}"> | ADMIN</a>
		<a sec:authorize="hasAuthority('admin')" th:href="@{/hello}"> | HELLO</a>
		<br/><hr/>
        <form th:action="@{/logout}" method="post" sec:authorize="hasAuthority('admin')">
            <input type="submit" class="btn btn-primary" value="注销"/>
        </form>
	</p>
</body>
</html>

index.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:th="http://www.thymeleaf.org"
	xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
<title>主页</title>
<link rel="stylesheet" th:href="@{static/css/bootstrap.min.css}"/>
<style type="text/css">
body { padding: 40px; }
</style>
</head>
<body>
	<h1>INDEX</h1>
	<br/>你好:<a sec:authentication="name"></a>
	<p>
		<a sec:authorize="hasAuthority('user')" th:href="@{/index}"> INDEX</a>
		<a sec:authorize="hasAuthority('admin')" th:href="@{/admin}"> | ADMIN</a>
		<a sec:authorize="hasAuthority('user')" th:href="@{/hello}"> | HELLO</a>
		<br/><hr/>
        <form th:action="@{/logout}" method="post">
            <input type="submit" class="btn btn-primary" value="注销"/>
        </form>
	</p>
</body>
</html>

login.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta content="text/html;charset=UTF-8"/>
<title>登录</title>
<link rel="stylesheet" th:href="@{static/css/bootstrap.min.css}"/>
<style type="text/css">
body { padding: 20px; }
.starter-template { width:350px; padding: 0 40px; text-align: center; }
</style>
</head>
<body>
	<p>
		<a th:href="@{/index}"> INDEX</a>
		<a th:href="@{/admin}"> | ADMIN</a>
		<a th:href="@{/hello}"> | HELLO</a>
		<br/>
	</p>
	<hr/>
    <div class="starter-template">
     <p th:if="${param.logout}" class="bg-warning">已成功注销</p><!-- 1 -->
	<p th:if="${param.error}" class="bg-danger">有错误,请重试</p> <!-- 2 -->
	<h2>使用用户名密码登录</h2>
	<form name="form"  th:action="@{/login}" action="/login" method="POST"> <!-- 3 -->
		<div class="form-group">
			<label for="username">账号</label>
			<input type="text" class="form-control" name="username" value="" placeholder="账号" />
		</div>
		<div class="form-group">
			<label for="password">密码</label>
			<input type="password" class="form-control" name="password" placeholder="密码" />
		</div>
		<div class="form-group">
			<input type="submit" id="login" value="登录" class="btn btn-primary" />
		</div>

	</form>
    </div>
</body>
</html>

源码下载地址:待补充

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,你的问题是如何使用springboot+springsecurity+mybatis来实现用户的注册和登录功能,并提供主界面的权限管理。 首先,我们需要创建一个Spring Boot项目,并将以下依赖添加到项目中: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.19</version> </dependency> ``` 接下来,我们需要创建一个User实体类,并在数据库中创建一个名为user的表,包含id、username、password、email等字段。 然后,我们需要创建一个UserMapper接口,用于与数据库交互。在该接口中,我们可以定义一些方法,如根据用户名查询用户信息、添加用户信息等。 接着,我们需要创建一个UserService类,在该类中,我们可以调用UserMapper接口中的方法来实现具体的业务逻辑,如用户注册、用户登录等。 在Spring Security中,我们需要创建一个SecurityConfig配置类,用于配置安全策略。在该类中,我们可以定义一些权限控制的规则,如哪些URL需要认证、哪些URL不需要认证等。 最后,我们需要创建一个Controller类,在该类中,我们可以调用UserService类中的方法来处理具体的请求,如注册、登录等。 以上是一个简单的使用springboot+springsecurity+mybatis实现用户注册和登录功能的流程,具体实现细节可以参考相关文档或案例代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值