觉得有帮助请点赞关注收藏~~~
一、什么是Spring Security
Spring Security是一个专门针对Spring应用系统的安全框架,充分利用了Spring框架的依赖注入和AOP功能,为Spring应用系统提供安全访问控制解决方案。
在Spring Security安全框架中,有两个重要概念。一个是授权(authorization),另一个是认证(ahtuentication)。授权即确定用户在当前应用系统下所拥有的功能权限。认证即确认用户访问当前系统的身份
二、Spring Security的基本使用
1:适配器
Spring Security为Web应用提供了一个适配器类WebSecurityConfigurerAdapter 该类实现了WebSecurityConfigurer<WebSecurity>接口,并提供了两个configure方法用于认证和授权操作
2:用户认证
使用AuthenticationManagerBuilder的inMemoryAuthentication()方法可以添加在内存中的用户,并给用户 指定角色权限
3:请求授权
常用方法如下
三、Spring Boot对Spring Security的支持
在Spring Boot应用中 只需引入spring-boot-starter-security依赖即可使用Spring Security安全框架,这是因为Spring Boot对Spring Security提供了自动配置功能。
接下来通过使用基于Spring Data JPA的Spring Security安全框架来进行实战
1:修改pom.xml文件 添加以下内容
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.45</version> </dependency>
2:配置application.properties文件
server.servlet.context-path=/ch7_1 ### ##数据源信息配置 ### #数据库地址 spring.datasource.url=jdbc:mysql://localhost:3306/springbootjpa?characterEncoding=utf8 #数据库用户名 spring.datasource.username=root #数据库密码 spring.datasource.password=root #数据库驱动 spring.datasource.driver-class-name=com.mysql.jdbc.Driver #### #JPA持久化配置 #### #指定数据库类型 spring.jpa.database=MYSQL #指定是否在日志中显示SQL语句 spring.jpa.show-sql=true #指定自动创建、更新数据库表等配置,update表示如果数据库中存在持久化类对应的表就不创建,不存在就创建对应的表 spring.jpa.hibernate.ddl-auto=update #让控制器输出的JSON字符串格式更美观 spring.jackson.serialization.indent-output=true spring.thymeleaf.cache=false logging.level.org.springframework.security=trace
3:创建用户和权限 持久化的实体类
用户代码如下
package com.ch.ch7_1.entity; import java.io.Serializable; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table; import javax.persistence.Transient; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @Entity @Table(name = "user") @JsonIgnoreProperties(value = { "hibernateLazyInitializer"}) public class MyUser implements Serializable{ private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String username; private String password; //这里不能是懒加载lazy,否则在MyUserSecurityService的loadUserByUsername方法中获得不到权限 @ManyToMany(cascade = {CascadeType.REFRESH}, fetch = FetchType.EAGER) @JoinTable(name = "user_authority",joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "authority_id")) private List<Authority> authorityList; //repassword不映射到数据表 @Transient private String repassword; public int getId() { return id; } public void setId(int 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<Authority> getAuthorityList() { return authorityList; } public void setAuthorityList(List<Authority> authorityList) { this.authorityList = authorityList; } public String getRepassword() { return repassword; } public void setRepassword(String repassword) { this.repassword = repassword; } }
权限代码如下
package com.ch.ch7_1.entity; import java.io.Serializable; import java.util.List; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.Table; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @Entity @Table(name = "authority") @JsonIgnoreProperties(value = { "hibernateLazyInitializer"}) public class Authority implements Serializable{ private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; @Column(nullable = false) private String name; @ManyToMany(mappedBy = "authorityList") @JsonIgnore private List<MyUser> userList; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<MyUser> getUserList() { return userList; } public void setUserList(List<MyUser> userList) { this.userList = userList; } }
4:创建数据访问层接口
package com.ch.ch7_1.repository; import org.springframework.data.jpa.repository.JpaRepository; import com.ch.ch7_1.entity.MyUser; public interface MyUserRepository extends JpaRepository<MyUser, Integer>{ //根据用户名查询用户,方法名命名符合Spring Data JPA规范 MyUser findByUsername(String username); }
5:创建业务层
接口代码如下
package com.ch.ch7_1.service; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.ui.Model; import com.ch.ch7_1.entity.MyUser; public interface UserService { public String register(MyUser userDomain); public String loginSuccess(Model model); public String main(Model model); public String deniedAccess(Model model); public String logout(HttpServletRequest request, HttpServletResponse response); }
实现类代码如下
package com.ch.ch7_1.service; import java.util.ArrayList; import java.util.List; 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.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.stereotype.Service; import org.springframework.ui.Model; import com.ch.ch7_1.entity.Authority; import com.ch.ch7_1.entity.MyUser; import com.ch.ch7_1.repository.MyUserRepository; @Service public class UserServiceImpl implements UserService{ @Autowired private MyUserRepository myUserRepository; /** * 实现注册 */ @Override public String register(MyUser userDomain) { String username = userDomain.getUsername(); List<Authority> authorityList = new ArrayList<Authority>(); //管理员权限 if("admin".equals(username)) { Authority a1 = new Authority(); Authority a2 = new Authority(); a1.setId(1); a1.setName("ROLE_ADMIN"); a2.setId(2); a2.setName("ROLE_DBA"); authorityList.add(a1); authorityList.add(a2); }else {//用户权限 Authority a1 = new Authority(); a1.setId(3); a1.setName("ROLE_USER"); authorityList.add(a1); } userDomain.setAuthorityList(authorityList); //加密密码 String secret = new BCryptPasswordEncoder().encode(userDomain.getPassword()); userDomain.setPassword(secret); MyUser mu = myUserRepository.save(userDomain); if(mu != null)//注册成功 return "/login"; return "/register";//注册失败 } /** * 用户登录成功 */ @Override public String loginSuccess(Model model) { model.addAttribute("user", getUname()); model.addAttribute("role", getAuthorities()); return "/user/loginSuccess"; } /** * 管理员登录成功 */ @Override public String main(Model model) { model.addAttribute("user", getUname()); model.addAttribute("role", getAuthorities()); return "/admin/main"; } /** * 注销用户 */ @Override public String logout(HttpServletRequest request, HttpServletResponse response) { //获得用户认证信息 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if(authentication != null) { //注销 new SecurityContextLogoutHandler().logout(request, response, authentication); } return "redirect:/login?logout"; } /** * 没有权限拒绝访问 */ @Override public String deniedAccess(Model model) { model.addAttribute("user", getUname()); model.addAttribute("role", getAuthorities()); return "deniedAccess"; } /** * 获得当前用户名称 */ private String getUname() { return SecurityContextHolder.getContext().getAuthentication().getName(); } /** * 获得当前用户权限 */ private String getAuthorities() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); List<String> roles = new ArrayList<String>(); for (GrantedAuthority ga : authentication.getAuthorities()) { roles.add(ga.getAuthority()); } return roles.toString(); } }
此处代码太多 需要源码请点赞关注收藏后评论区留言或私信博主
6:创建控制器类
7:创建应用的安全控制相关实现
8:创建用于测试的视图页面
页面效果如下
登录首页
拒绝访问页面
用户登录界面
用户注册界面