SpringBoot 配合 SpringSecurity 实现自动登录功能的代码

下面我就来详细讲解一下 “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技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • 学习 WSH 的理由小结

    学习 WSH(Windows Script Host)的理由有很多,我在这里总结了一些重要的理由,帮助大家更好地了解 WSH 并开始学习。 学习 WSH 的理由小结 1. WSH 是 Windows 操作系统自带的脚本处理引擎 WSH 是和 Windows 操作系统一起安装的,它提供了一种可以运行脚本程序的环境,使得我们可以使用脚本语言来处理各种操作系统的任…

    Java 2023年5月26日
    00
  • Java实现简单字符生成器代码例子

    下面我就来详细讲解Java实现简单字符生成器代码的攻略。 步骤一:了解需求 在开始编写代码之前,首先要明确这个代码的需求。我们需要编写一个简单的字符生成器,根据指定的规则生成一定数量的字符并输出。 步骤二:编写基础代码 在开始编写功能代码之前,我们要先编写一些基础代码,如获取用户输入的信息、生成指定范围内的随机数等。下面是代码示例: import java.…

    Java 2023年5月18日
    00
  • javascript es6的常用语法你知道吗

    JavaScript ES6 常用语法 ES6是JavaScript的一种标准,也被称为ECMAScript2015,它为JavaScript添加了很多新特性和语法。以下是ES6中常用的几种语法。 let & const 在ES6之前,我们只能使用var关键字来声明变量。而在ES6中,我们可以使用let和const关键字来声明变量。 let用来声明一…

    Java 2023年6月15日
    00
  • 使用Java实现大小写转换实例代码

    使用Java实现大小写转换可以通过常用的String类提供的方法来实现,下面是实现的完整攻略: 1. 使用toUpperCase和toLowerCase方法 Java中String类提供了两个方法来实现大小写转换,分别是toUpperCase方法和toLowerCase方法。 toUpperCase方法:将字符串中的所有字符转换为大写字母; toLowerC…

    Java 2023年5月23日
    00
  • JavaSpringBoot报错“NotSupportedException”的原因和处理方法

    原因 “NotSupportedException” 错误通常是以下原因引起的: 数据库问题:如果您的数据库存在问题,则可能会出现此错误。在这种情况下,需要检查您的数据库并确保它们正确。 数据库驱动问题:如果您的数据库驱动存在问题,则可能会出现此错误。在这种情况下,需要检查您的数据库驱动并确保它们正确。 数据库版本问题:如果您的数据库版本与您的数据库驱动不兼…

    Java 2023年5月4日
    00
  • C#纯代码实现打字游戏

    下面是“C#纯代码实现打字游戏”的完整攻略: 步骤一:创建项目和界面 打开Visual Studio,创建一个新的Windows Forms Application项目。 在Form中设计游戏界面,可以添加文本框用于显示单词或句子,添加计时器用于计时等。 步骤二:生成单词列表 在代码中定义一个string类型的数组,存储所有可能出现的单词或句子。 可以使用R…

    Java 2023年5月19日
    00
  • Java Properties作为集合三个方法详解

    当我们使用Java进行编程时,经常需要使用配置文件来存储一些关键的配置信息,于是Java提供了一个名为Properties的类来处理这个问题。Properties是一个Map集合,其中的key和value都必须是字符串类型。下面将详细讲解Java Properties作为集合的三个常用方法:getProperty、setProperty和load。 getP…

    Java 2023年6月15日
    00
  • 基于springBoot配置文件properties和yml中数组的写法

    以下是基于springBoot配置文件properties和yml中数组的写法的完整攻略: 配置文件格式 在Spring Boot中,可以使用.properties或.yml格式的配置文件,其中.yml格式相较于.properties更为简洁直观。 .properties格式 .properties格式中数组的写法可以使用以下方式: my.array[0]=…

    Java 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部