引入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); } }