Springboot+Mybatis+Springsecurity+MySQL的整合

这几天由于需求,整合了一下Springsecurity的安全框架,独乐乐不如众乐乐和大家分享一下,避免不必要的坑。## 标题

这里奉上GitHub克隆地址点击https://github.com/xjjxltzf/CSDN.git

进入正题,本次将采用本人的理解讲解该安全框架的整合。

项目结构:
一个小dome
Springboot+Mybatis+Springsecurity+MySQL的整合_第1张图片

pom.xml导入的依赖



	4.0.0

	com.demo.SpringBootMyBatisSpringSecurity
	SpringBootMyBatisSpringSecurity
	0.0.1-SNAPSHOT
	jar

	SpringBootMyBatisSpringSecurity
	SpringBootMyBatisSpringSecurity

	
	
		org.springframework.boot
		spring-boot-starter-parent
		1.5.9.RELEASE
		 
	

	
		UTF-8
		UTF-8
		1.8
	

	

		
		
			org.springframework.boot
			spring-boot-starter-thymeleaf
		

		
		
			org.springframework.boot
			spring-boot-starter-test
			test
		
		
		
			org.springframework.boot
			spring-boot-starter-security
		
		
		
			org.thymeleaf.extras
			thymeleaf-extras-springsecurity4
		

		
		
			org.mybatis.spring.boot
			mybatis-spring-boot-starter
			1.3.1
		
		
		
			mysql
			mysql-connector-java
			5.1.32		
		
		
		
		
		
	      org.projectlombok
	      lombok    
	    

		
		
			junit
			junit
		

		
			org.springframework.security
			spring-security-core
		
		
			org.springframework.security
			spring-security-web
		
		
			org.springframework.security
			spring-security-config
		
		
			org.springframework.security
			spring-security-taglibs
		
		
	

	
		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
			
				org.apache.maven.plugins
				maven-compiler-plugin
				3.1
				
					true
					true
					${JAVA8_HOME}/bin/javac
				
			
		
	
	


整合采用yml+mybatis-config.xml进行配置

application.yml

spring:
   datasource:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql:///数据库名?serverTimezone=UTC
      username: 你的数据库用户名
      password: 你的数据库密码
   
   
mybatis: 
	#这里是Mybatis的配置文件映射路径
   config-location: classpath:mybatis-config.xml
      

mybatis-config.xml





    	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
  
  
  	  
  

*---------------------------------------------------------配置搞定开始撸码-------------------------------------------------

国际惯例

1.实体类

com.demo.pojo
>DbUser.java

package com.demo.pojo;
import lombok.Data;

/*
 * 测试用户对象
 */
@Data
public class DbUser {

	private String username;//用户名
	private String password;//用户密码
	private Integer access_level;//用户权限标识
	private String description;//用户权限描述
}

2.数据访问层

com.demo.dao
>DataMapper.java

package com.demo.dao;

import com.demo.pojo.DbUser;

/*
 * Mybatis数据映射,
 */
public interface DataMapper {
	DbUser getUserLoginInfo(String username);
}

>DataMapper.xml






		
	

实现层

com.demo.impl

这里开始写有关Springsecurity的代码,此实现层功能描述:调用DAO层通过用户输入的用户名查询用户记录返回用户信息

package com.demo.impl;

import java.util.ArrayList;
import java.util.Collection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
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.demo.dao.DataMapper;
import com.demo.pojo.DbUser;

/*
 * 自定义用户名密码校验实现,一定要@Service注解,然后在配置类中加载(重载configure)
 */
@Service
public class UserDetailInfo implements UserDetailsService{

	//数据库操作
	@Autowired
	private DataMapper dbDataMapper;

	//必须重写,自己来实现登陆验证
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		System.out.println("这里点击登录后进");
		System.out.println("user["+username+"] is logining...");
		DbUser dbUser = dbDataMapper.getUserLoginInfo(username);
		if(dbUser==null)
		{
			System.out.println("user["+username+"] is not exist!");
			throw new UsernameNotFoundException(username + " do not exist!");  
		}
		System.out.println("Get user info from db: "+ dbUser.toString());

		UserDetails	user = new User(dbUser.getUsername(), dbUser.getPassword(), true, true, true, true,
				getAuthorities(dbUser.getAccess_level())); 

		return user;
	}

	/**
	 * 获得访问角色权限
	 */
	public Collection getAuthorities(Integer access) {

		Collection authorities = new ArrayList<>();      

		//所有的用户默认拥有ROLE_USER权限	
		authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
		if (access.compareTo(0) == 0) {
			// 如果参数access为0.则拥有ROLE_ADMIN权限
			authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
		}else if(access.compareTo(2) == 0) {
			// 如果参数access为2.则拥有ROLE_TAO权限
			authorities.add(new SimpleGrantedAuthority("ROLE_TAO"));
		}
		
		//最终这里返回的是用户权限集合
		return authorities;
	}

}

**

进入Springsecurity核心配置类

**

com.demo.config
>WebSecurityConfig.java

package com.demo.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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

import com.demo.impl.UserDetailInfo;

/*
 * 配置类:
 * 重写它的方法来设置一些web安全的细节,如配置security的登录页面和传递的参数,公共路径权限属性等
 */
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)  //控制权限到请求方法级别
//@EnableGlobalMethodSecurity(prePostEnabled = true)//方法调用前鉴权
@EnableWebSecurity //禁用Boot的默认Security配置,配合@Configuration启用自定义配置(需要扩展WebSecurityConfigurerAdapter)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	

	//自定义认证对象
	@Autowired
	private UserDetailInfo urlUserService;

	//HTTP请求安全处理
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		System.out.println("这里程序运行第二个进入");
		//请求权限配置
		http.authorizeRequests()
		//指定了/和/home不需要任何认证就可以访问,
		.antMatchers("/", "/login","/**").permitAll()
		//任何请求,登录后方可访问。
		.anyRequest().authenticated() 
		//登陆界面参数
		.and().formLogin().loginPage("/login").defaultSuccessUrl("/hello")/*.usernameParameter("username").passwordParameter("password")*/.permitAll()
		//设置注销成功后跳转页面,默认是跳转到登录页面
		.and().logout().logoutSuccessUrl("/login").permitAll()
		//权限访问失败界面,关键,如果不定义的话会抛出异常
		.and().exceptionHandling().accessDeniedPage("/denied")
		;
		http.csrf().disable();
	}

	/*
	 * 身份验证管理生成器。一定要重载!!!不然自定义的登陆校验不生效
	 * */
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		System.out.println("不用测试了这里程序运行第一个进入");
		auth.userDetailsService(urlUserService)
	
		/*.passwordEncoder(new PasswordEncoder() {
			//可以自己定义密码匹配规则
			@Override
			public String encode(CharSequence rawPassword) {
				return (String)rawPassword;//MD5Util.encode((String) rawPassword);
			}

			@Override
			public boolean matches(CharSequence rawPassword, String encodedPassword) {
				System.out.println(encodedPassword + "---" + (String)rawPassword);
				return encodedPassword.equals((String) rawPassword);
			}
		})*/;
	}
	
}

MvcConfig.java
视图解析器可以少写controller中的映射代码

package com.demo.config;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Component
/**
 * 视图解析器
 * @author TAO
 *
 */
public class MvcConfig extends WebMvcConfigurerAdapter  {

	//直接页面跳转,不经过Controller,这样在没有任何处理业务的时候,快捷的页面转向定义会节省好多代码
	 @Override
	 public void addViewControllers(ViewControllerRegistry registry)
	 {
	 	//这里主要配置不需要任何认证就可以访问映射
		registry.addViewController("/login").setViewName("login");
		registry.addViewController("/").setViewName("login");
		//registry.addViewController("/hello").setViewName("hello");
		//registry.addViewController("/login").setViewName("login");
		//registry.addViewController("/denied").setViewName("denied");
		//registry.addViewController("/admin").setViewName("admin");
	 }
}

com.demo.controller
>HelloController.java

package com.demo.controller;

import org.springframework.security.access.annotation.Secured;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/*
 * 网络控制层:返回数据的controller。这里映射到resources目录下的templates的html页面。 * 
 */
@Controller
public class HelloController {

//这里对比MvcConfig.java视图映射器,那里写了这里就可以少写这些代码
	/*@RequestMapping("/")
	public String index() {
		return "home";
	}
	@RequestMapping("/home")
	public String home() {
		return "home";
	}*/

	/*当我们访问这个URL的时候,Spring Security会帮我们验证当前用户是否有权限访问该地址。
	 *官方推荐的鉴权注解方式,控制权限到请求方法级别。可通过三种方式的注解:
	 *注解方式1:@Secured, spring自带的注解方法:securedEnabled = true
	 *注解方式2:@PreAuthorize,方法调用前注解:securedEnabled = true
	 *注解方式2:@RolesAllowed,非spring框架: jsr250Enabled = true
	 *注意1:角色要填全名!
	 *注意2:一定要在自定义的WebSecurityConfigurerAdapter中添加注解。@EnableGlobalMethodSecurity(axx=bxx)!axx/bxx见上
	 */
	@Secured("ROLE_USER")
	@RequestMapping("/hello")
	//@PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_USER')")
	public String hello(){
		return "hello";
	}

	@RequestMapping(value = "/login")
	public String login() {
		return "login";
	}

	@RequestMapping(value = "/logout")
	public String logout() {
		return "home";
	}

	@RequestMapping(value = "/denied")
	public String denied() {
		return "denied";
	}

	@Secured("ROLE_ADMIN")
	@RequestMapping(value = "/admin")
	//@PreAuthorize("hasAnyRole('ROLE_ADMIN')")
	public String admin() {
		return "admin";
	}
}


com.demo
>DemoApplication.java

程序入口

package com.demo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
//这个表示mybatis自动扫描dao接口的包名,
@MapperScan("com.demo") 
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}
}

*------------------------------------------java代码搞定开始静态界面-------------------------------------------------
login.html登入界面,hello.html欢迎页-用户权限页,denied.html-拒绝访问页,admin.html管理员页
Springboot+Mybatis+Springsecurity+MySQL的整合_第2张图片

静态界面代码##

*login.html




Spring Security Example


	
无效的用户名和密码。.
您已经注销了.

使用账号密码登录

hello.html




Hello World!


	

普通。每个人都可以参观。

这是管理员访问.

这是用户访问。

这是TAO才能访问

Click here 退出

Click here 去管理员页面

admin.html




Admin Page


	

管理员页

Click here 普通界面

Click here 退出

denied.html




拒绝访问


	

您的访问被拒绝

这是一个拒绝访问的页面

Click here 去你好页面

Click here 退出

引入Springsecurity安全框架后的效果

login.html
有点简陋主要学习框架
这里直接/或者login都可以,其他映射路径全部拦截到login这里
Springboot+Mybatis+Springsecurity+MySQL的整合_第3张图片

登入成功后
用的是admin用户

图中的(这是用户访问。)
这里每个用户都有一个ROLE_USER这样的权限,解释一下:由于静态资源路径这样写/static/** 这样放不过,去所以自能写成/星星(这里/星星转义打不出理解一下你懂得)
然后所有请求都要配置一个@Secured(“ROLE_ADMIN”)这样的权限请求,(注意除/,和/login不然登入页面都看不到)

其实这里有三个权限提示但是这里只显示了两个,一个是任何用户都能看得到的红箭头标记了,上面解释了,另一个就是当前登入用户的权限(用的是admin用户 —就是管理员)

这里静态资源也出来了
Springboot+Mybatis+Springsecurity+MySQL的整合_第4张图片

当前是admin用户所以可以去管理员界面
Springboot+Mybatis+Springsecurity+MySQL的整合_第5张图片

我们再来看看TAO用户
图片文字有解释
Springboot+Mybatis+Springsecurity+MySQL的整合_第6张图片

//当前为TAO权限我们点击一下去管理员界面试一下Springboot+Mybatis+Springsecurity+MySQL的整合_第7张图片

这个界面是权限拒接界面上面有提到denied.html

GitHub下载地址

https://github.com/xjjxltzf/CSDN.git

你可能感兴趣的:(Spring)