SpringSecurity 表单登录的实现

yizhihongxing

实现SpringSecurity表单登录需要以下步骤:

  1. 导入依赖

需要在项目中导入SpringSecurity相关的依赖包,例如:

<dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-web</artifactId>
   <version>5.5.0</version>
</dependency>
<dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-config</artifactId>
   <version>5.5.0</version>
</dependency>
  1. 配置SpringSecurity

在SpringBoot项目中,可以通过在配置类上加上@EnableWebSecurity注解,来启用SpringSecurity。接着在配置类中,可以定义拦截器规则、用户信息等相关配置,例如:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private MyUserDetailsService myUserDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailsService)
            .passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/login").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/home")
            .permitAll()
            .and()
            .logout()
            .permitAll();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

上述配置中,我们配置了一个自定义的用户详情服务MyUserDetailsService,并且指定了密码加密的实现类BCryptPasswordEncoder。在configure(HttpSecurity http)方法中,我们设定了拦截器规则,对于URI为/login的请求,不需要进行身份验证,对于其他URI的请求,需要进行身份验证。

  1. 创建登录页面

接下来,创建一个登录页面,代码中含有一个POST请求方法,用于接收用户提交的登录表单。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Login</title>
    </head>

    <body>
        <div>
            <form action="/login" method="POST">
                <label for="username">用户名:</label>
                <input type="text" id="username" name="username">
                <br/>
                <label for="password">密码:</label>
                <input type="password" id="password" name="password">
                <br/>
                <input type="submit" value="登录">
            </form>
        </div>
    </body>    
<html>
  1. 实现自定义用户详情服务

在前面的配置中,我们指定了一个自定义的用户详情服务MyUserDetailsService,需要自己实现该服务来获取用户的详细信息,例如:

@Service
public class MyUserDetailsService implements UserDetailsService {
    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);

        if (user == null) {
            throw new UsernameNotFoundException(username + " not found");
        }

        Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
        for (Role role : user.getRoles()) {
            authorities.add(new SimpleGrantedAuthority(role.getName()));
        }

        return new org.springframework.security.core.userdetails.User(user.getUsername(),
                user.getPassword(), authorities);
    }
}

通过自定义用户详情服务,可以使用自己的业务逻辑从数据库或其他持久化层获取用户的信息。上述代码中,我们使用了一个自定义的实体类User来封装用户的信息,同时也使用了自定义的实体类Role来封装用户的角色信息。

  1. 定义自定义登录成功处理器

我们可以定义一个自定义的登录成功处理器来处理登录成功后的相关业务逻辑。例如:

@Component
public class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws ServletException, IOException {
        response.setStatus(HttpServletResponse.SC_OK);
    }
}

上述代码中,定义了一个CustomAuthenticationSuccessHandler类,继承了SimpleUrlAuthenticationSuccessHandler类,并重写了onAuthenticationSuccess方法。该方法会在用户登录成功后被调用,并可以在该方法中,处理登录成功后的业务逻辑。在该示例中,我们只是简单地设置了HTTP响应状态为200。

示例1:实现SpringSecurity表单登录的完整示例

下面是一个完整的SpringBoot项目中的完整示例:

@SpringBootApplication
public class SpringBootSecurityApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootSecurityApplication.class, args);
    }

    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Autowired
        private MyUserDetailsService myUserDetailsService;

        @Autowired
        private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(myUserDetailsService)
                .passwordEncoder(passwordEncoder());
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/home")
                .successHandler(customAuthenticationSuccessHandler)
                .permitAll()
                .and()
                .logout()
                .permitAll();
        }

        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    }

    @Service
    public class MyUserDetailsService implements UserDetailsService {
        @Autowired
        private UserRepository userRepository;

        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            User user = userRepository.findByUsername(username);

            if (user == null) {
                throw new UsernameNotFoundException(username + " not found");
            }

            Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
            for (Role role : user.getRoles()) {
                authorities.add(new SimpleGrantedAuthority(role.getName()));
            }

            return new org.springframework.security.core.userdetails.User(
                    user.getUsername(), user.getPassword(), authorities);
        }
    }

    @Component
    public class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
        @Override
        public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, 
                Authentication authentication) throws ServletException, IOException {
            response.setStatus(HttpServletResponse.SC_OK);
        }
    }

    @Entity
    public class User {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String username;
        private String password;

        @ManyToMany(fetch = FetchType.EAGER)
        private Set<Role> roles;

        // getter & setter
    }

    @Entity
    public class Role {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String name;

        // getter & setter
    }

    public interface UserRepository extends JpaRepository<User, Long> {
        User findByUsername(String username);
    }
}

示例2:使用 Thymeleaf 模板引擎实现 SpringSecurity 表单登录

下面是一个使用Thymeleaf模板引擎的SpringBoot项目中的完整示例:

@SpringBootApplication
public class SpringBootSecurityApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootSecurityApplication.class, args);
    }

    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Autowired
        private MyUserDetailsService myUserDetailsService;

        @Autowired
        private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(myUserDetailsService)
                .passwordEncoder(passwordEncoder());
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/home")
                .successHandler(customAuthenticationSuccessHandler)
                .permitAll()
                .and()
                .logout()
                .permitAll();
        }

        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    }

    @Service
    public class MyUserDetailsService implements UserDetailsService {
        @Autowired
        private UserRepository userRepository;

        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            User user = userRepository.findByUsername(username);

            if (user == null) {
                throw new UsernameNotFoundException(username + " not found");
            }

            Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
            for (Role role : user.getRoles()) {
                authorities.add(new SimpleGrantedAuthority(role.getName()));
            }

            return new org.springframework.security.core.userdetails.User(
                    user.getUsername(), user.getPassword(), authorities);
        }
    }

    @Component
    public class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
        @Override
        public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                Authentication authentication) throws ServletException, IOException {
            response.setStatus(HttpServletResponse.SC_OK);
        }
    }

    @Entity
    public class User {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String username;
        private String password;

        @ManyToMany(fetch = FetchType.EAGER)
        private Set<Role> roles;

        // getter & setter
    }

    @Entity
    public class Role {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String name;

        // getter & setter
    }

    public interface UserRepository extends JpaRepository<User, Long> {
        User findByUsername(String username);
    }

    @Controller
    public class LoginController {
        @GetMapping("/login")
        public String login() {
            return "login";
        }
    }

    @Controller
    public class HomeController {
        @GetMapping("/home")
        public String home() {
            return "home";
        }
    }
}

上述代码中,我们使用了Thymeleaf来实现了一个自定义的登录页面,在该登录页面中,通过表单提交用户名和密码,并将数据提交到/loginURI。同时,也定义了一个自定义的控制器HomeController,在用户登录成功后,会跳转到该控制器中定义的/homeURI。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringSecurity 表单登录的实现 - Python技术站

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

相关文章

  • java验证用户是否已经登录 java实现自动登录

    下面是关于Java验证用户是否已经登录以及Java实现自动登录的完整攻略。 Java验证用户是否已经登录 要验证用户是否已经登录,可以通过以下步骤实现: 步骤一:获取用户的登录状态 在用户登录成功后,可以将其信息保存在Session中。当需要验证用户是否已登录时,只需获取Session中的用户信息,即可判断用户是否已经登录。以下是示例代码: HttpSess…

    Java 2023年6月16日
    00
  • Springboot jar文件如何打包zip在linux环境运行

    这里就为您详细讲解如何将Spring Boot应用打包成Jar文件并在Linux环境中部署运行。 1. 生成Jar包 在使用Maven进行构建的项目中,我们可以使用以下Maven命令将应用程序打包成可执行的Jar文件: mvn clean package 执行该命令后,Maven将会在target目录下生成一个可执行的Jar包,其名称通常为{artifact…

    Java 2023年5月19日
    00
  • spring boot输入数据校验(validation)的实现过程

    下面我来给您讲解关于spring boot输入数据校验(validation)的实现过程的完整攻略。 1. 简介 Spring Boot提供了一种简单的方法来在Web应用程序中轻松实现输入数据的校验。它可以通过使用声明式注解进行实现,这些注解在处理表单输入时特别有用。 1.1 常用的校验注解 Spring Boot中常用的校验注解包括: @NotNull:验…

    Java 2023年5月20日
    00
  • 如何使用Java安全管理框架?

    如何使用Java安全管理框架? Java安全管理框架是Java平台提供的一个安全机制,通过使用Java安全管理框架,开发者可以实现对Java应用程序的安全控制。 安装Java安全管理框架 Java安全管理框架已经集成到JDK中,无需另行安装。 配置Java安全管理策略文件 Java安全管理框架通过配置Java安全管理策略文件来实现安全控制。Java安全管理策…

    Java 2023年5月11日
    00
  • Java8如何构建一个Stream示例详解

    下面就详细讲解Java8如何构建一个Stream示例。 什么是Stream? Stream是Java8新引入的流式处理API,它可以使得对集合的操作更加高效,简洁,易于维护。通过使用Stream,我们可以完成众多集合操作,如转化、过滤、聚合等等。 构建一个Stream实例 构建一个由数值组成的流 可以通过如下代码构建一个由数值组成的流。 Stream<…

    Java 2023年5月26日
    00
  • Java通过BCrypt加密过程详解

    Java通过BCrypt加密过程详解 什么是BCrypt BCrypt是一种密码学哈希函数,它可以将密码或者任何数据转换为唯一的字符串,这个字符串通常被用作密码的存储与验证。BCrypt通过不同的“盐”(salt)和迭代次数运算来实现哈希过程,让破译者难以直接破解密码。 BCrypt的基本使用方法 在Java项目中,我们可以通过Spring Security…

    Java 2023年5月20日
    00
  • java开发SpringBoot参数校验过程示例教程

    下面我来详细讲解“Java开发Spring Boot参数校验过程示例教程”的完整攻略。 什么是参数校验 在Web开发中,为了保证数据的准确性和完整性,在接口中进行参数校验是一个很重要的环节。参数校验通常包括验证参数的格式、数据类型、取值范围等。 使用Spring Boot进行参数校验 Spring Boot提供了一种方便快捷的方式来进行参数校验。使用Spri…

    Java 2023年5月19日
    00
  • Java实现代码块耗时测算工具类

    确定需求 首先确定需求,我们需要一个工具类,可以帮助我们测试某个代码块的执行耗时。这个工具类需要满足以下特点: 可以重复使用,多个代码块测试时不需要重复编写计时逻辑。 能够准确地计算代码块的执行时间。 能够方便地输出测试结果,以便进行比较和分析。 设计实现方案根据需求,我们可以设计一个名为 CodeTimer 的工具类,该类中包含以下方法: start():…

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