下面我就来详细讲解一下 “SpringBoot 配合 SpringSecurity 实现自动登录功能的代码”的完整攻略。
什么是自动登录功能
自动登录(Remember Me)是指用户可以选择保存登录状态,保留一定时间不失效。这样用户可以在再次打开网站时,不需要重新输入用户名密码,而是直接使用之前的登录信息登录进去。
操作步骤
1. 导入相关依赖
在 pom.xml 中添加以下依赖:
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2. 配置 Spring Security
创建一个类来继承 WebSecurityConfigurerAdapter 类,同时重写其 configure() 方法,在该方法中添加相关配置,如下所示:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyUserDetailService myUserDetailService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/login").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/index")
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login")
.and()
.rememberMe()
.tokenRepository(persistentTokenRepository())
.rememberMeCookieName("my-remember-me")
.tokenValiditySeconds(60 * 60 * 24 * 7)
.userDetailsService(myUserDetailService)
.and()
.csrf()
.ignoringAntMatchers("/h2-console/**");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailService);
}
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
tokenRepository.setDataSource(dataSource);
return tokenRepository;
}
}
3. 编写 UserDetails 实现类
在项目中新建一个实现了 UserDetails 接口的类 MyUserDetail,添加必要的字段和方法。
public class MyUserDetail implements UserDetails {
private String username;
private String password;
private List<SimpleGrantedAuthority> authorities;
public MyUserDetail(String username, String password, List<SimpleGrantedAuthority> authorities) {
this.username = username;
this.password = password;
this.authorities = authorities;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
// 没有过期
@Override
public boolean isAccountNonExpired() {
return true;
}
// 未锁定
@Override
public boolean isAccountNonLocked() {
return true;
}
// 密码未过期
@Override
public boolean isCredentialsNonExpired() {
return true;
}
// 未禁用
@Override
public boolean isEnabled() {
return true;
}
}
4. 编写 UserDetailsService 实现类
实现 UserDetailsService 接口,重写其 loadUserByUsername() 方法,在其中查询用户信息。
@Service
public class MyUserDetailService implements UserDetailsService {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
String sql = "select * from user where username = ?";
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, username);
if (list.isEmpty()) {
throw new UsernameNotFoundException("用户不存在!");
}
Map<String, Object> map = list.get(0);
String password = map.get("password").toString();
List<SimpleGrantedAuthority> authorities = Collections.singletonList(new SimpleGrantedAuthority("USER"));
return new MyUserDetail(username, password, authorities);
}
}
5. 编写登录页面和成功页面
<!-- 登录页面 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login Page</title>
</head>
<body>
<h1>Login Page</h1>
<form action="/login" method="post">
<label for="username">Username</label>
<input type="text" id="username" name="username" required>
<br>
<label for="password">Password</label>
<input type="password" id="password" name="password" required>
<br>
<input type="checkbox" id="rememberMe" name="remember-me">
<label for="rememberMe">Remember me</label>
<br>
<input type="submit" value="Login">
</form>
</body>
</html>
<!-- 成功页面 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Success Page</title>
</head>
<body>
<h1>Login Success!</h1>
<a href="/logout">Logout</a>
</body>
</html>
示例1
第一个示例,访问 /admin,需要有 ADMIN 权限才可以访问。
@RestController
@RequestMapping("/admin")
@PreAuthorize("hasRole('ADMIN')")
public class AdminController {
@GetMapping
public String hello() {
return "Hello, Admin!";
}
}
示例2
第二个示例,展示如何在 Controller 中获取当前登录用户信息。
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(Authentication authentication) {
String username = authentication.getName();
return "Hello, " + username + "!";
}
}
总结
这就是 SpringBoot 配合 SpringSecurity 实现自动登录的完整攻略,主要的步骤就是导入相关依赖,配置 Spring Security,编写 UserDetails、UserDetailsService 实现类,以及编写登录页面和成功页面。示例代码展示了如何在 Controller 中获取当前登录用户信息,以及如何限制特定用户访问某些资源。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot 配合 SpringSecurity 实现自动登录功能的代码 - Python技术站