Spring Security配置
第一步,空Spring Boot环境。
暂时不添加了Spring Security依赖。
第二步,确保项目能够正常运行。
启动启动项 Application.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
@EnableAutoConfiguration
public class AuthorityApplication {
public static void main(String[] args) {
SpringApplication.run(AuthorityApplication.class, args);
}
// localhost:8080/
@RequestMapping(value = "/")
public String home() {
return "这是根路径";
}
// localhost:8080/hello
@RequestMapping(value = "/hello")
public String hello() {
return "hello";
}
}
确保Spring Boot项目能够正常启动。

第三步,添加了Spring Security依赖。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
重启Application,访问 localhost:8080/ ,出现以下界面,自动跳转至 http://localhost:8080/login ,需要登录,实现了认证功能。

第四步,自定义Spring Security配置文件 SpringSecurityCustomConfig.java 。
1.实现对主路径放行、其他路径请求需要验证、注销操作允许任意权限访问、表单登录允许任意权限访问。
2.对js、css、images不做拦截。
import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration// 配置文件 @EnableWebSecurity// 打开web支持 public class SpringSecurityCustomConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { // 决定那些请求被拦截 http.authorizeRequests() .antMatchers("/").permitAll()// 主路径放行 .anyRequest().authenticated()// 其他请求需经过验证 .and() .logout().permitAll()// 注销操作允许任意权限访问 .and() .formLogin().permitAll();// 表单登录允许任意权限访问 http.csrf().disable();// 关闭默认的csrf认证 } @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/js'/**", "/css/**", "/images/**");// 对js、css、images不做拦截 } }
访问主路径 http://localhost:8080/ ,不需要验证。

访问其他路径 http://localhost:8080/hello ,需要验证。出现以下界面,自动跳转至 http://localhost:8080/login

Spring Security常见案例
案例一:只需登录
不希望花太多时间做登录功能,也不希望数据库存储登录用户名和密码。
自定义Spring Security配置文件 SpringSecurityCustomConfig.java ,通知系统在内存中有一个用户名为“admin”,用户密码为“123456”的用户,该用户角色为“ADMIN”。
访问需要验证的路径 http://localhost:8080/hello ,分别输入错误信息和正确信息。


访问 http://localhost:8080/login?logout 即可登出。
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration// 配置文件
@EnableWebSecurity// 打开web支持
public class SpringSecurityCustomConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// Spring Security提供了一套基于内存的验证
auth.inMemoryAuthentication()
.withUser("admin")
.password("123456")
.roles("ADMIN");// 自定义角色
// 可以添加若干个auth.inMemoryAuthentication()
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// 决定那些请求被拦截
http
.authorizeRequests()
.antMatchers("/").permitAll()// 主路径放行
.anyRequest().authenticated()// 其他请求需经过验证
.and()
.formLogin().permitAll()// 表单登录允许任意权限访问
.and()
.logout().permitAll();// 注销操作允许任意权限访问
http.csrf().disable();// 关闭默认的csrf认证
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/js'/**", "/css/**", "/images/**");// 对js、css、images不做拦截
}
}
案例二:指定角色,权限按角色分配
自定义Spring Security配置文件 SpringSecurityCustomConfig.java ,通知系统在内存中有一个用户名为“caiji”,用户密码为“caiji”的用户,该用户角色为“USER”。
访问需要验证的路径 http://localhost:8080/hello

访问需要验证的路径 http://localhost:8080/roleAuth ,caiji无权限访问,admin可以访问
Application.java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController @EnableAutoConfiguration// Spring Boot会自动根据jar依赖自动配置项目 @EnableGlobalMethodSecurity(prePostEnabled = true)// 启动注解@PreAuthorize的作用 public class AuthorityApplication { public static void main(String[] args) { SpringApplication.run(AuthorityApplication.class, args); } // localhost:8080/ @RequestMapping(value = "/") public String home() { return "这是根路径"; } // localhost:8080/hello @RequestMapping(value = "/hello") public String hello() { return "hello ADMIN"; } // localhost:8080/hello @PreAuthorize("hasRole('ROLE_ADMIN')")// RoleVote中定义需要添加前缀 @RequestMapping(value = "/roleAuth") public String roleAuth() { return "hello USER"; } }
SpringSecurityCustomConfig.jaca @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // Spring Security提供了一套基于内存的验证 auth.inMemoryAuthentication() .withUser("admin") .password("123456") .roles("ADMIN");// 自定义角色 // 可以添加若干个auth.inMemoryAuthentication() auth.inMemoryAuthentication().withUser("caiji").password("caiji").roles("USER");// USER用户 }
案例三:数据库管理用户
新增 UserService 类,实现 UserDetailsService 。
UserService.java 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.Component; @Component public class UserService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { return null; } }
将用户admin、caiji放入数据库,使用UserService管理。
SpringSecurityCustomConfig.java @Autowired private UserService userService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // Spring Security提供了一套基于内存的验证 // auth.inMemoryAuthentication() // .withUser("admin") // .password("123456") // .roles("ADMIN");// 自定义角色 // // 可以添加若干个auth.inMemoryAuthentication() // auth.inMemoryAuthentication().withUser("caiji").password("caiji").roles("USER");// USER用户 auth.userDetailsService(userService); }
自定义密码管理验证,新建 PasswordCustomEncoder 类,实现 PasswordEncoder 接口。
Spring Security提供了许多对密码加密的封装类,此处以MD5加密为例。
PasswordCustomEncoder.java import org.springframework.security.authentication.encoding.Md5PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; /** * @author tabjin * create at 2019-06-29 09:05 * @program authority * @description */ public class PasswordCustomEncoder implements PasswordEncoder { private final static String SALT = "123456"; /** * 加密方法,对原始密码加密 * @param charSequence * @return */ @Override public String encode(CharSequence charSequence) { Md5PasswordEncoder md5PasswordEncoder = new Md5PasswordEncoder(); return md5PasswordEncoder.encodePassword(charSequence.toString(), SALT);// 加密并附加123456 } /** * 匹配方法,对原始密码和加密后密码匹配 * @param charSequence * @param s * @return */ @Override public boolean matches(CharSequence charSequence, String s) { Md5PasswordEncoder md5PasswordEncoder = new Md5PasswordEncoder(); return md5PasswordEncoder.isPasswordValid(s, charSequence.toString(), SALT);// 保证盐值和加密时一样 } }
回到定义认证的类 SpringSecurityCustomConfig.java
SpringSecurityCustomConfig.java @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 自定义处理 auth.userDetailsService(userService).passwordEncoder(new PasswordCustomEncoder());// 指定好UserService后添加自定义密码验证器 // Spring Security 默认数据库处理,表结构位于users.ddl auth.jdbcAuthentication().usersByUsernameQuery("").passwordEncoder(new PasswordCustomEncoder()); }

浙公网安备 33010602011771号