Spring Boot企业级开发(一)Spring Security

简介

Spring Security是专门针对基于Spring的项目的安全框架,充分利用了依赖注入和AOP来实现安全的功能。

实战

1:新建Spring Boot项目,添加依赖JPA、Security、Thymeleaf;并添加数据库驱动以及Thymeleaf的Spring Security的支持:

<dependency>
			<groupId>org.thymeleaf.extras</groupId>
			<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>

<dependency>
		    <groupId>mysql</groupId>
		    <artifactId>mysql-connector-java</artifactId>
		    <version>5.1.38</version>
</dependency>

2:配置属性
application.properties

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/book
spring.datasource.username=root
spring.datasource.password=123456


logging.level.org.springframework.security= INFO

spring.thymeleaf.cache=false

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

实体类用户

@Entity
//实现UserDetails接口,我们的用户实体即为Spring Security所使用的用户
public class SysUser implements UserDetails{ 
	
	private static final long serialVersionUID = 1L;
	@Id
	@GeneratedValue
	private Long id;
	private String username;
	private String password;
	//配置用户与角色多对多的关系
	@ManyToMany(cascade = {CascadeType.REFRESH},fetch = FetchType.EAGER)
	private List<SysRole> roles;
	
	
	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() { //重写getAuthorities方法,将用户的角色作为权限
		List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
		List<SysRole> roles=this.getRoles();
		for(SysRole role:roles){
			auths.add(new SimpleGrantedAuthority(role.getName()));
		}
		return auths;
	}
	@Override
	public boolean isAccountNonExpired() {
		return true;
	}
	@Override
	public boolean isAccountNonLocked() {
		return true;
	}
	@Override
	public boolean isCredentialsNonExpired() {
		return true;
	}
	@Override
	public boolean isEnabled() {
		return true;
	}
	
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public List<SysRole> getRoles() {
		return roles;
	}
	public void setRoles(List<SysRole> roles) {
		this.roles = roles;
	}	
}

实体类角色

@Entity
public class SysRole {
	@Id
	@GeneratedValue
	private Long id;
	private String name;
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

数据展示类

public class Msg {
	private String title;
	private String content;
	private String etraInfo;
	
	public Msg(String title, String content, String etraInfo) {
		super();
		this.title = title;
		this.content = content;
		this.etraInfo = etraInfo;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public String getEtraInfo() {
		return etraInfo;
	}
	public void setEtraInfo(String etraInfo) {
		this.etraInfo = etraInfo;
	}
	
}

数据访问

public interface SysUserRepository extends JpaRepository<SysUser, Long>{
	
	SysUser findByUsername(String username);//根据用户名查出用户

}

自定义的CustomUserService

public class CustomUserService implements UserDetailsService { 
	//UserDetailsService接口用于返回用户相关数据。它有loadUserByUsername()方法,根据username查询用户实体,可以实现该接口覆盖该方法,实现自定义获取用户过程。
	@Autowired
	SysUserRepository userRepository;

	@Override
	public UserDetails loadUserByUsername(String username) { //重写loadUserByUsername方法获得用户
		
		SysUser user = userRepository.findByUsername(username); 
		if(user == null){
			throw new UsernameNotFoundException("用户名不存在");
		}
		
		return user; //当前的用户实现了UserDetails接口,可直接返回给Spring Security使用
	}

}

Spring MVC配置

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter{
	
	@Override
	public void addViewControllers(ViewControllerRegistry registry) {
		registry.addViewController("/login").setViewName("login");//访问/login转向login.html
	}

}

Spring Security配置

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{//扩展Spring  Security配置需继承WebSecurityConfigurerAdapter
	
	@Bean
	UserDetailsService customUserService(){ //注册CustomUserService的Bean
		return new CustomUserService(); 
	}
	
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(customUserService()); //添加自定义的user detail service
		
	}
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.authorizeRequests()
						.anyRequest().authenticated() //所以请求需要认证才能访问
						.and()
						.formLogin()
							.loginPage("/login")
							.failureUrl("/login?error")
							.permitAll() //登录页面可任意访问
						.and()
						.logout().permitAll(); //注销请求可任意访问
	}
}

登录页面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="@{css/bootstrap.min.css}"/>
<style type="text/css">
	body {
  padding-top: 50px;
}
.starter-template {
  padding: 40px 15px;
  text-align: center;
}
</style>
</head>
<body>
	
	 <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <a class="navbar-brand" href="#">Spring Security演示</a>
        </div>
        <div id="navbar" class="collapse navbar-collapse">
          <ul class="nav navbar-nav">
           <li><a th:href="@{/}"> 首页 </a></li>
           
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav>
     <div class="container">

      <div class="starter-template">
       <p th:if="${param.logout}" class="bg-warning">已成功注销</p><!-- 注销成功后显示 -->
			<p th:if="${param.error}" class="bg-danger">有错误,请重试</p> <!-- 登录有错误时显示 -->
			<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>
				<input type="submit" id="login" value="Login" class="btn btn-primary" />
			</form>
      </div>

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

首页home.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" 
	  xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"><!--thymeleaf为我们提供的Spring Security的标签支持  -->
<head>
<meta content="text/html;charset=UTF-8"/>
<title sec:authentication="name"></title> <!-- 获得当前用户的用户名 -->
<link rel="stylesheet" th:href="@{css/bootstrap.min.css}" />
<style type="text/css">
body {
  padding-top: 50px;
}
.starter-template {
  padding: 40px 15px;
  text-align: center;
}
</style>
</head>
<body>
	 <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <a class="navbar-brand" href="#">Spring Security演示</a>
        </div>
        <div id="navbar" class="collapse navbar-collapse">
          <ul class="nav navbar-nav">
           <li><a th:href="@{/}"> 首页 </a></li>
           
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav>
    
    
     <div class="container">

      <div class="starter-template">
      	<h1 th:text="${msg.title}"></h1>
		
		<p class="bg-primary" th:text="${msg.content}"></p>
		
		<div sec:authorize="hasRole('ROLE_ADMIN')"> <!-- 当前用户权限为ROLE_ADMIN时,才可显示标签内内容 -->
		 	<p class="bg-info" th:text="${msg.etraInfo}"></p>
		</div>	
		
		<div sec:authorize="hasRole('ROLE_USER')"> <!-- 当前用户权限为ROLE_USER时,才可显示标签内内容-->
		 	<p class="bg-info">无更多信息显示</p>
		</div>	
		
        <form th:action="@{/logout}" method="post">
            <input type="submit" class="btn btn-primary" value="注销"/><!-- 注销的默认路径为/logout,需通过POST请求提交 -->
        </form>
      </div>

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

控制器

@Controller
public class HomeController {
	
	@RequestMapping("/")
	public String index(Model model){
		Msg msg =  new Msg("测试标题","测试内容","额外信息,只对管理员显示");
		model.addAttribute("msg", msg);
		return "home";
	}

}

运行测试

使用权限为ROLE_USER的用户登录时:
这里写图片描述

使用权限为ROLE_ADMIN的用户登录时:
这里写图片描述

使用错误的账号密码登录时:
这里写图片描述

注销成功后:
这里写图片描述

参考书籍:Spring Boot 实战
以上只是学习所做的笔记, 以供日后参考!!!

猜你喜欢

转载自blog.csdn.net/z1790424577/article/details/81141170
今日推荐