SpringBoot+Spring security+Mysql


项目格式
---------------承上启下线------------
在这里插入图片描述

1.导入pom配置文件

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>2020</groupId>
	<artifactId>HandlerInterceptor</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<name>HandlerInterceptor</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	<!-- 管理bean -->
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.2.RELEASE</version>
		<relativePath />

	</parent>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!--jsp界面jstl依赖(下拉选择) -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
		</dependency>
		<!-- servlet 依赖 -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
		</dependency>
		<!--使jsp页面生效,进行访问 -->
		<dependency>
			<groupId>org.apache.tomcat.embed</groupId>
			<artifactId>tomcat-embed-jasper</artifactId>
		</dependency>
		<!-- spring-boot-starter-security依赖 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<!-- 启动shiro -->
		<!-- <dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring-boot-web-starter</artifactId>
			<version>1.4.0</version>
		</dependency> -->
		<!-- 整合Thymeleaf -->
		<!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> 
			</dependency> -->
		<!--通用mapper,tk.mapper -->
		<dependency>
			<groupId>tk.mybatis</groupId>
			<artifactId>mapper-spring-boot-starter</artifactId>
			<version>1.1.4</version>
		</dependency>
		<!--对数据库的支持 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		<!--数据库mysql的支持 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<!--json的支持 -->
		<dependency>
			<groupId>net.sf.json-lib</groupId>
			<artifactId>json-lib</artifactId>
			<version>2.4</version>
			<classifier>jdk15</classifier>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.3.2</version>
		</dependency>
		<!-- @Data依赖 -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.12</version>
		</dependency>
         <dependency>
             <groupId>commons-collections</groupId>
             <artifactId>commons-collections</artifactId>
             <version>3.2.2</version>
         </dependency>
    	 <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
        </dependency>
        <dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.0</version>
</dependency>
	</dependencies>
	<build>
		<finalName>HandlerInterceptor</finalName>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
					<!-- 设置编码为 UTF-8 -->
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

2.配置全局配置文件(application.properties)

#jsp页面处理
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp


#MYSQL数据库连接
spring.jpa.database = MYSQL
spring.datasource.url = jdbc:mysql://localhost/hand?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
spring.datasource.username =账号
spring.datasource.password =密码
#spring.datasource.password =密码
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.druid.initial-size=1
spring.datasource.druid.min-idle=1
spring.datasource.druid.max-active=20
spring.datasource.druid.test-on-borrow=true
spring.datasource.druid.stat-view-servlet.allow=true
mybatis.typeAliasesPackage=com.hand.pojo
mybatis.mapperLocations=classpath:mappers/*.xml
mybatis.configuration.mapUnderscoreToCamelCase=true
mybatis.configuration.cacheEnabled=false

3.启动类:HandWeb.java

package com.hand.web;

import org.mybatis.spring.annotation.MapperScan;
//import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.transaction.annotation.EnableTransactionManagement;


@SpringBootApplication
@ComponentScan("com.hand")
@MapperScan("com.hand.mapper")
@EnableTransactionManagement//开启事务---可以不写
public class HandWeb {
	public static void main(String[] args) {
		SpringApplication.run(HandWeb.class, args);
	}
	
}

4.配置Security的适配器

package com.hand.config;

import java.io.IOException;

import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.LockedException;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hand.service.UserService;

/**
 * 适配器
 * Security的认证策略
 * @author DoubleC
 *
 */
@Configuration
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter{
	@Autowired
	UserService userService;
	@Autowired
	CustomExpiredSessionStrategy customExpiredSessionStrategy;

	/*
	 * @Autowired JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
	 */
	/**
	 * 密码进行加密
	 * @return
	 */
	@Bean 
	PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder(10);
		//return NoOpPasswordEncoder.getInstance();
	}
	

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		// TODO Auto-generated method stub
		//super.configure(auth);
//		auth.inMemoryAuthentication()
//			.withUser("root").password("909396").roles("ADMIN","DBA")
//			.and()
//			.withUser("admin").password("909396").roles("ADMIN","USER")
//			.and()
//			.withUser("sang").password("909396").roles("USER");
		/**
		 * 将用户与数据库进行对接,并将密码加密匹配
		 */
		auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
	}
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// TODO Auto-generated method stub
		//super.configure(http);
		http
		.authorizeRequests()
			/**
			 * 资源管理权限配置
			 */
			.antMatchers("/static/**").permitAll()
			.antMatchers("/images/**").permitAll()
			.antMatchers("/WEB/**").permitAll()
			.antMatchers("/dynamic/**").access("hasAnyRole('admin','dba','user')")
			
			//.access("hasRole('ADMIN') and hasRole('DBA') and hasRole('USER')")
			//.antMatchers("/user/**").permitAll()
			.antMatchers("/admin/**")
			.hasRole("admin")
			.antMatchers("/user/**")
			.access("hasAnyRole('admin','dba','user')")
			//.access("hasRole('admin') and hasRole('user')")
			.antMatchers("/db/**")
			.access("hasRole('ADMIN') and hasRole('DBA')")
			
			.anyRequest()
			.authenticated()
			.and()
			/**
			 * 登录表单详细配置
			 */
			.formLogin()
			.loginPage("/login")
			.loginProcessingUrl("/user/login")
				/*
				 * .usernameParameter("username") .passwordParameter("password")
				 */
			.permitAll()
			/**
			 * 登录成功实现数据交互
			 */
			.successHandler(new AuthenticationSuccessHandler() {
				
				@Override
				public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
						Authentication auth) throws IOException, ServletException {
					// TODO Auto-generated method stub
					/**
					 * 前后端数据交互配置
					 */
					Object principal = auth.getPrincipal();
					response.setContentType("application/json;charset=utf-8");
					PrintWriter out = response.getWriter();
					response.setStatus(200);
					Map<String, Object> map = new HashMap<>();
					map.put("status", 200);
					map.put("msg", principal);
					ObjectMapper om = new ObjectMapper();
					out.write(om.writeValueAsString(map));
					out.flush();
					out.close();
				}
			})
			/**
			 * 登录失败进行数据交互
			 */
			.failureHandler(new AuthenticationFailureHandler() {
				
				@Override
				public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
						AuthenticationException e) throws IOException, ServletException {
					// TODO Auto-generated method stub
					response.setContentType("application/json;charset=utf-8");
					PrintWriter out = response.getWriter();
					response.setStatus(401);
					Map<Object, Object> map = new HashMap<>();
					map.put("status", 401);
					if(e instanceof LockedException) {
						map.put("msg", "账户被锁定,登录失败!");
					}else if(e instanceof BadCredentialsException) {
						map.put("msg", "账户或密码输入错误,登录失败!");
					}else if(e instanceof DisabledException) {
						map.put("msg", "账户被禁用,登录失败");
					}else if(e instanceof AccountExpiredException) {
						map.put("msg", "账户已过期,登录失败");
					}else if(e instanceof CredentialsExpiredException) {
						map.put("msg", "密码已过期,登录失败");
					}else {
						map.put("msg", "登录失败");
					}
					ObjectMapper om = new ObjectMapper();
					out.write(om.writeValueAsString(map));
					out.flush();
					out.close();
				}
			})
			/**
			 * 注销登录配置
			 */
			.and()
			.logout()
			.logoutUrl("/logout")
			.clearAuthentication(true)
			.invalidateHttpSession(true)
			.addLogoutHandler(new LogoutHandler() {

				@Override
				public void logout(HttpServletRequest request, HttpServletResponse response,
						Authentication auth) {
					// TODO Auto-generated method stub
					
				}
				
			})
			.logoutSuccessHandler(new LogoutSuccessHandler() {

				@Override
				public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
						Authentication auth) throws IOException, ServletException {
					// TODO Auto-generated method stub
					//注销以后返回界面
					response.sendRedirect("/login_page");
				}
				
			})
			.permitAll()
			/**
			 * 解决jsp页面iframe全部失效问题
			 * X-Frame-Options' to 'deny'故障
			 * iframe全部失效了
			 * index:
			 * 1 Refused to display 
			 * 'http://localhost:8080/dynamic/page/ecg.jsp'
			 *  in a frame because it set 'X-Frame-Options' to 'deny'.
			 */
			.and()
			.headers().frameOptions().disable()
			
			.and()
			/**
			 * 解决账号同时在线问题,在同一时间只允许一个一台机器在线
			 */
			.sessionManagement().maximumSessions(1).expiredSessionStrategy(customExpiredSessionStrategy).expiredUrl("/login");
			http
			.csrf()
			.disable();
			
			http.headers().cacheControl();
			//http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
			
	        http.logout().logoutSuccessUrl("/login");
			http.rememberMe().rememberMeParameter("remember");
		
	}
}

4.1(UserService)

UserService.java

package com.hand.service;

import javax.servlet.http.HttpSession;

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;

import com.hand.mapper.UserMapper;
import com.hand.pojo.User;
@Service
public class UserService implements UserDetailsService{
	@Autowired
	UserMapper userMapper;
	@Autowired
	HttpSession session;
	
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		// TODO Auto-generated method stub
		//根据用户名获取用户的基本信息
		User user=userMapper.loadUserByUsername(username);
		session.setAttribute("user", user);
//		UsernamePasswordToken token = new UsernamePasswordToken();
//		Subject subject = SecurityUtils.getSubject();
//		try {
//			subject.login(token);
//		} catch (Exception e) {
//			// TODO: handle exception
//		}

		if(user==null||user.equals(" ")) {
			System.out.println("账号或密码错误!");
			throw new UsernameNotFoundException("账户不存在!");
		}
		//获取用户的权限,并将用户权限表嵌入user中
		user.setRoles(userMapper.getUserRolesByUid(user.getId()));
		return user;
	}
	
}

4.2(CustomExpiredSessionStrategy)

CustomExpiredSessionStrategy.java(不是必须类,可要可不要)

package com.hand.config;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;

import org.springframework.security.web.session.SessionInformationExpiredEvent;
import org.springframework.security.web.session.SessionInformationExpiredStrategy;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.ObjectMapper;

@Component
public class CustomExpiredSessionStrategy implements SessionInformationExpiredStrategy {

    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException, ServletException {
        Map<String,Object> map = new HashMap<>();
        map.put("code",0);
        map.put("msg","已经另一台机器登录,您被迫下线。" + event.getSessionInformation().getLastRequest());
        String s = objectMapper.writeValueAsString(map);
        event.getResponse().setContentType("application/json;charset=UTF-8");
        event.getResponse().getWriter().write(s);
        event.getResponse().sendRedirect("/login");
    }
}

4.3(RegService)

RegService.java (用户注册,给密码进行加密,存入数据库)

package com.hand.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import com.hand.mapper.UserMapper;
import com.hand.pojo.User;

@Service
public class RegService {
	@Autowired
	UserMapper userMapper;
	public Boolean reg(String username,String password) {
		BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(10);
		String encodePassword=encoder.encode(password);
		return saveToOb(username,encodePassword);
	}

	private Boolean saveToOb(String username, String encodePassword) {
		User user = new User();
		user.setUsername(username);
		user.setPassword(encodePassword);
		/**
		 * 注册新用户
		 * 根据用户名查询用户ID
		 * 根据用户ID给用户赋予权限最低权限(用户权限)
		 */
		Integer userId=userMapper.userInsert(username,encodePassword);
		Integer uid=userMapper.getUserId(username);
		Integer user_roldId=userMapper.insertUserRole(uid);
		if(userId>=1) {
			if(user_roldId>=1)
				return true;
			return false;
		}
		return false;
	}
}

4.4(UserMapper )

package com.hand.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Param;

import com.hand.common.MyMapper;
import com.hand.pojo.Role;
import com.hand.pojo.User;

public interface UserMapper extends MyMapper<User>{

	User loadUserByUsername(String username);

	List<Role> getUserRolesByUid(String id);

	int userInsert(@Param("username")String username, @Param("password")String encodePassword);

	Integer getUserId(String username);

	Integer insertUserRole(Integer id);


}

4.5 (Role )

package com.hand.pojo;

public class Role {
	private Integer id;
	private String name;
	private String namezh;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getNamezh() {
		return namezh;
	}
	public void setNamezh(String namezh) {
		this.namezh = namezh;
	}
	@Override
	public String toString() {
		return "Role [id=" + id + ", name=" + name + ", namezh=" + namezh + "]";
	}
	
}

4.6(User )

package com.hand.pojo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.persistence.Id;
import javax.persistence.Transient;

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


public class User implements UserDetails,Serializable{
	@Id
	private String id;
	private String username;
	private String password;
	private Boolean enabled;
	private Boolean locked;
	@Transient
	private List<Role> roles;

	/*
	 * public User(Integer id, String username, String password, Boolean enabled,
	 * Boolean locked) { // TODO Auto-generated constructor stub
	 * this.username=username; this.password=password; this.enabled=enabled;
	 * this.locked=locked; }
	 */
	

	public String getId() {
		return id;
	}

	public String getUsername() {
		return username;
	}

	public String getPassword() {
		return password;
	}

	public void setId(String id) {
		this.id = id;
	}

	/*
	 * public Boolean getEnabled() { return enabled; }
	 * 
	 * public void setEnabled(Boolean enabled) { this.enabled = enabled; }
	 */

	public Boolean getLocked() {
		return locked;
	}

	public void setLocked(Boolean locked) {
		this.locked = locked;
	}

	

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

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

	public void setUsername(String username) {
		this.username = username;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", password=" + password + ", enabled=" + enabled
				+ ", locked=" + locked + ", roles=" + roles + "]";
	}





	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		// TODO Auto-generated method stub
		List<SimpleGrantedAuthority> authorities = new ArrayList<>();
		for(Role role:roles) {
			authorities.add(new SimpleGrantedAuthority(role.getName()));
		}
		return authorities;
	}



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

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

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

	@Override
	public boolean isEnabled() {
		// TODO Auto-generated method stub
		/*
		 * if (StringUtils.isEmpty(getEnabled()) ) { return !enabled; }
		 */
		return enabled;
	}
	@Override
	public int hashCode() {
		// TODO Auto-generated method stub
		return username.hashCode();
	}
	@Override
	public boolean equals(Object obj) {
		// TODO Auto-generated method stub
		return this.toString().equals(obj.toString());
	}
	

}

5.书写SQL语句

<?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.hand.mapper.UserMapper">
	<select id="loadUserByUsername" resultType="com.hand.pojo.User">
		select * from user where username=#{username}
	</select>
	<select id="getUserRolesByUid" resultType="com.hand.pojo.Role">
		select * from role r,user_role ur where r.id=ur.rid and ur.uid=#{id}
	</select>
	<insert id="userInsert">
		insert into user(id,username,password,enabled,locked) values(null,#{username},#{password},1,0);
	</insert>
	<select id="getUserId" resultType="java.lang.Integer">
		select id from user where username=#{username}
	</select>
	<!-- 给用户赋予最低等权限3(普通用户权限) -->
	<insert id="insertUserRole">
		insert into user_role(id,uid,rid) values(null,#{id},3)
	</insert>
	
</mapper> 

6.数据表构造

CREATE TABLE USER(
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY UNIQUE,
username VARCHAR(32) NOT NULL UNIQUE ,
PASSWORD VARCHAR(255),
enabled TINYINT(1) NOT NULL,
locked TINYINT(1) NOT NULL
) ENGINE =INNODB DEFAULT CHARSET=utf8;

CREATE TABLE role(
id INT(11) NOT NULL AUTO_INCREMENT,
NAME VARCHAR(32) NOT NULL,
namezh VARCHAR(32) NOT NULL ,
PRIMARY KEY (id)
) ENGINE =INNODB DEFAULT CHARSET=utf8;




-- 权限角色关系表--
CREATE TABLE user_role(
  id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY UNIQUE,
  uid INT(11) NOT NULL ,
  rid INT(11) NOT NULL,
  KEY idx_uid(uid),
  KEY idx_rid(rid)
) ENGINE = INNODB DEFAULT CHARSET = utf8;

7.表数据展示

给用户表插入几条数据
权限表
用户与权限关联表

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值