SpringBoot 整合Spring Security框架

时间:2024-01-14 13:43:32

引入maven依赖

 <!-- 放入spring security依赖  -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

Spring Security配置类

SecurityConfig.java

package com.example.demo.security;

import org.springframework.context.annotation.Bean;
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 org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; /**
* 配置类
* @EnableWebSecurity 开启Security功能
*/
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) //允许通过注解的方法拦截
public class SecurityConfig extends WebSecurityConfigurerAdapter { /**
* 用于密码加密
* @return
*/
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
} /**
* 进行授权
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception{
/**
*定制请求的授权规则
* permitAll() 表示都允许访问
* hasRole("admin") 表示用户必须有admin的角色才能访问
*/ http.authorizeRequests().antMatchers("/").permitAll()
.antMatchers("/add").hasRole("admin"); /**
* 开启自动配置的登录功能,如果没有权限就会来到登录页面
* 1、 /login 请求进入登录页,可自定义
* 表单的用户名name 默认为username
* 密码name 默认为 password
*
* usernameParameter 参数可以设置表单中用户名的name
* passwordParameter 参数可以设置表单中密码的name
*
* 2、重定向到/login?error 表示登录失败
* 定义登录页 /toLogin 请求
* loginProcessingUrl("") 设置登录提交的请求链接
*/
http.formLogin().
loginPage("/toLogin")
.usernameParameter("username")
.passwordParameter("pwd")
.loginProcessingUrl("/login"); /**
* 关闭csrf功能,禁用跨站请求,进行安全访问
*/
http.csrf().disable(); /**
* 开启记住我功能,登录信息保存cookie,
* 默认保存两周
* rememberMeParameter 参数设置表单中 记住我 的name名
*/
http.rememberMe().rememberMeParameter("rememberMe"); /**
* 开启自动配置的注销功能
* 1、访问 logout 表示用户注销,清空session
* 可以通过
* Authentication authentication=SecurityContextHolder.getContext().getAuthentication();
* authentication.getPrincipal(); 获取登录用户信息
*
*
*
* 2、注销成功默认会请求 /login?logout (登录页面)
* 可以通过logoutSuccessUrl() 方法自定义退出成功后的地址
*/
http.logout().logoutSuccessUrl("/"); } /**
* 认证 springboot 2.1.x可以直接使用
* 密码编码 :passwordEncoder
* 在spring security 5.0+ 新增了加密方法
*
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
auth.userDetailsService(new UserServiceConfig());
}
}

Spring Security 查询用户信息类

UserServiceConfig.java

package com.example.demo.security;

import com.example.demo.entity.CmsUser;
import com.example.demo.entity.Role;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
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.security.crypto.password.PasswordEncoder; import java.util.ArrayList;
import java.util.List; @Configuration
public class UserServiceConfig implements UserDetailsService { @Autowired
private PasswordEncoder passwordEncoder; @Autowired
private UserService userService; /**
* 根据用户名查找用户
* @param username 用户在浏览器输入的用户名
* @return UserDetails 是spring security自己的用户对象
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
CmsUser cmsUser =userService.findByUsername(username); if (cmsUser==null){
//表示查询不到用户,认证失败
return null;
} /**
* 这里为了演示进行了密码加密,实际开发中应该是用户在进行注册时就对密码进行加密,
* 这里直接取数据库的密码进行比对即可,不需要再进行加密
*/
String password=passwordEncoder.encode(cmsUser.getPassword()); /**
* 添加该用户的角色信息
* roleName 是角色名称
*/
List<SimpleGrantedAuthority> authorities=new ArrayList<>();
List<Role> roles=cmsUser.getRoles();
for (Role role:roles){
authorities.add(new SimpleGrantedAuthority(role.getRoleName()));
} return new User(cmsUser.getUsername(),password,authorities);
} }

自定义错误页面

ErrorPageConfig.java

package com.example.demo.security;

import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.ErrorPageRegistrar;
import org.springframework.boot.web.server.ErrorPageRegistry;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus; /**
* 定制错误页面
*/
@Configuration
public class ErrorPageConfig implements ErrorPageRegistrar { @Override
public void registerErrorPages(ErrorPageRegistry registry) { /**
* 定制禁止访问错误页面
* /403 是错误页面的跳转请求
*/
ErrorPage errorPage=new ErrorPage(HttpStatus.FORBIDDEN,"/403"); registry.addErrorPages(errorPage); }
}