项目创建
pom 依赖
1 2 3 4 5 6 7 8
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
|
Demo
写一个 Controller
1 2 3 4 5 6 7 8
| @RestController public class HelloController {
@RequestMapping(value = "/hello") public String hello() { return "hello"; } }
|
启动项目测试,访问:http://localhost:8080/ ,默认跳转到登录页面
测试请求网址: http://localhost:8080/hello ,发现被 302 重定向到登录页面
只要加入依赖,项目的所有接口都会被自动保护起来,当用户从浏览器发送请求访问 /hello
接口时,服务端会返回 302
响应码,让客户端重定向到 /login
页面,用户在 /login
页面登录,登陆成功之后,就会自动跳转到 /hello
接口
默认情况下,登录的用户名是 user
,密码是项目启动时随机生成的字符串
登录以后可以发现 302 重定向到 /hello
接口
用户名密码配置
三种实现方案
配置文件
直接在 application.properties
文件中配置用户的基本信息
1 2
| spring.security.user.name=admin spring.security.user.password=123456
|
配置类
创建一个 Spring Security 的配置类,需要继承 WebSecurityConfigurerAdapter
类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); String encode = passwordEncoder.encode("123456"); auth.inMemoryAuthentication().withUser("root").password(encode).roles("admin"); auth.inMemoryAuthentication().withUser("zhang").password(encode).roles("user"); }
@Bean PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
|
自定义实现类
一、自定义编写一个实现类,可以实现从数据库加载用户名和密码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
@Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { List<GrantedAuthority> authorityList = AuthorityUtils.commaSeparatedStringToAuthorityList("role"); return new User("root", new BCryptPasswordEncoder().encode("123"), authorityList); } }
|
这里对 SpringSecurity 提供的 User 对象拓展更多的属性
继承 SpringSecurity 提供的 User 对象,拓展一个 userId 属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class LoginUser extends User { private Integer userId;
public LoginUser(String username, String password, Collection<? extends GrantedAuthority> authorities) { super(username, password, authorities); }
public LoginUser(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) { super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); }
public Integer getUserId() { return userId; }
public void setUserId(Integer userId) { this.userId = userId; } }
|
修改好的实现类
1 2 3 4 5 6 7 8 9 10 11
| @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { List<GrantedAuthority> authorityList = AuthorityUtils.commaSeparatedStringToAuthorityList("role"); LoginUser loginUser = new LoginUser(s, new BCryptPasswordEncoder().encode("123456"), authorityList); loginUser.setUserId(00001); return loginUser; }
|
二、创建配置类,指定使用哪个 userDetailService 实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Resource private UserDetailsService userDetailsService;
@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService); }
@Bean PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
|
测试访问:http://localhost:8080/hello