SpringSecurity 表单登录的实现

实现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日

相关文章

  • C#语法糖(Csharp Syntactic sugar)大汇总

    让我详细讲解“C#语法糖(Csharp Syntactic sugar)大汇总”的完整攻略。 什么是C#语法糖? C#语法糖,也称为Csharp Syntactic sugar,指的是一些C#编程语言中的语法结构,这些结构并不会让代码变得更加强大,但是却可以让代码变得更加简洁易懂。在实际编写程序时,使用C#语法糖可以提高代码可读性和可维护性。 具体的C#语法…

    Java 2023年5月19日
    00
  • Java毕业设计之多用户宿舍管理系统的实现

    Java毕业设计之多用户宿舍管理系统的实现攻略 1. 需求分析 多用户宿舍管理系统需要实现如下功能:1. 根据管理员账号和密码登录系统;2. 管理员可以添加、查询、修改和删除学生信息;3. 管理员可以添加、查询、修改和删除宿舍信息;4. 管理员可以将学生分配到某个宿舍;5. 学生可以使用学生账号和密码登录系统;6. 学生可以查询自己的宿舍信息,并进行相关操作…

    Java 2023年5月24日
    00
  • 使用Spark进行实时流计算的方法

    使用Spark进行实时流计算的方法包括以下步骤: 1. 设置 Spark Streaming 上下文 要使用 Spark Streaming 进行实时流计算,首先需要设置 Spark Streaming 上下文。使用 Scala 代码的示例: import org.apache.spark.SparkConf import org.apache.spark.…

    Java 2023年5月20日
    00
  • Java程序优化的作用是什么?

    Java程序优化的作用 Java程序优化是指在保持程序功能不变的前提下,通过优化代码结构、算法、资源利用等方面的手段提升程序的性能和效率。Java程序优化的作用体现在以下几个方面: 提升用户体验:优化程序性能可以减少用户等待时间,提高程序响应速度,从而提升用户体验。 节省资源开销:优化程序可以减少资源消耗,减少运行成本,从而提高整个系统的利用率。 提升系统稳…

    Java 2023年5月11日
    00
  • 常见的Java字节码插装工具有哪些?

    常见的Java字节码插装工具有很多,其中比较常用的有ASM、Javassist、Byte Buddy和Instrumentation,下面具体介绍它们的使用方法以及示例。 一、 ASM 1.1 简介 ASM是一个Java字节码操作框架,它可以用来动态生成和转换Java字节码。与Java自带的Instrumentation机制类似,ASM扫描字节码时,会向字节…

    Java 2023年5月11日
    00
  • 详解SpringBoot中异步请求和异步调用(看完这一篇就够了)

    下面我将为您详细讲解“详解SpringBoot中异步请求和异步调用(看完这一篇就够了)” 的完整攻略。 什么是异步请求和异步调用 在Web编程中,我们通常使用同步方式来处理客户端请求,即客户端向服务端发送请求后,服务端会一直等待直到完成响应,然后再返回响应结果。而异步方式则是一种非阻塞IO的处理模式,即客户端向服务端发送请求后,服务端不会立即返回响应结果,而…

    Java 2023年5月19日
    00
  • SpringMVC拦截器超详细解读

    以下是关于“SpringMVC拦截器超详细解读”的完整攻略,其中包含两个示例。 SpringMVC拦截器超详细解读 在SpringMVC中,拦截器是一种非常重要的组件,它可以在请求到达控制器方法之前或之后进行一些处理。本攻略将详细介绍SpringMVC拦截器的使用方法和注意事项。 拦截器的作用 拦截器可以在请求到达控制器方法之前或之后进行一些处理,如记录日志…

    Java 2023年5月16日
    00
  • Spring Integration概述与怎么使用详解

    Spring Integration概述 Spring Integration是Spring框架的一个扩展,提供了一种集成不同系统、应用、协议和数据格式的方式。它提供了许多现成的组件和模板,使得实现企业级集成变得更加便捷和高效。 Spring Integration采用基于消息的异步通信模型,所有的组件都是被设计成异步的最终接收者,而消息则负责在组件之间传递…

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