SpringBoot + Spring Security 基本使用及个性化登录配置详解

SpringBoot+SpringSecurity基本使用

1. 引入Spring Security

在pom.xml中添加Spring Security的依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

2. 编写SecurityConfig

创建一个继承自WebSecurityConfigurerAdapter的配置类,用于配置Spring Security相关内容。代码如下:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;

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

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

在上面的代码中,我们首先通过@EnableWebSecurity注解开启Web Security。然后,我们使用@Autowired注解将UserDetailsService注入到配置类中,UserDetailsService用于根据用户名获取用户信息。在configure方法中,我们将UserDetailsService传递给AuthenticationManagerBuilder,并使用passwordEncoder方法返回的PasswordEncoder对象对密码进行加密。PasswordEncoder用于加密用户密码。

3. 编写登录页

创建一个Controller,并在其中定义返回登录页面的方法。代码如下:

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

在上述示例中,我们使用了@GetMapping注解定义了一个GET请求。

4. 配置登录认证

我们需要创建一个实现UserDetailsService接口的类,并定义用于获取用户信息的方法。代码如下:

@Service
public class UserDetailsServiceImpl 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("用户不存在");
        }
        return user;
    }
}

在上面的代码中,我们通过@Service注解将UserDetailsServiceImpl注入到Spring容器中。然后,我们实现loadUserByUsername方法,该方法用于根据用户名查询用户信息。

5. 配置访问控制

我们可以通过方法authorizeRequests配置访问权限。代码如下:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/login", "/register").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().loginPage("/login").defaultSuccessUrl("/").permitAll()
                .and()
                .logout().permitAll();
    }

    @Autowired
    private UserDetailsService userDetailsService;

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

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

在上述示例中,我们定义了两个不需要授权即可访问的URL:/login/register。对于其他任何URL,用户必须先进行验证才能访问。在formLogin配置中,我们使用了loginPage方法指定了自定义的登录页面,通过defaultSuccessUrl方法配置默认成功跳转的URL。在logout配置中,我们允许用户进行注销操作。

SpringSecurity个性化登录配置详解

1. 美化登录页面

可以通过在resources/static下放置login.html文件,然后在SecurityConfig配置中配置loginPage方法指向该页面,从而实现美化登录页面的目的。

2. 自定义验证身份逻辑

我们可以通过传入一个AuthenticationProvider对象,使用自定义校验逻辑,该类需要实现AuthenticationProvider接口。示例代码如下:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(new AuthenticationProvider() {
            @Override
            public Authentication authenticate(Authentication authentication) throws AuthenticationException {
                String username = authentication.getName();
                String password = authentication.getCredentials().toString();
                if ("admin".equals(username) && "123456".equals(password)) {
                    List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
                    grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
                    return new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(), grantedAuthorities);
                } else {
                    throw new BadCredentialsException("用户名或密码错误");
                }
            }

            @Override
            public boolean supports(Class<?> aClass) {
                return true;
            }
        });
    }
}

在上面的代码中,我们自定义了一个AuthenticationProvider对象,该对象实现了authenticate方法,该方法用于验证用户身份是否正确。如果用户名和密码正确,我们返回一个UsernamePasswordAuthenticationToken对象,该对象保存了用户的认证信息。否则,我们抛出一个BadCredentialsException异常,该异常用于表示认证失败的情况。

3. 多方式登录

我们可以通过配置多个AuthenticationProvider对象,实现多种登录方式。示例代码如下:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setUserDetailsService(userDetailsService());
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());

        auth.authenticationProvider(daoAuthenticationProvider);

        InMemoryAuthenticationProvider inMemoryAuthenticationProvider = new InMemoryAuthenticationProvider();
        inMemoryAuthenticationProvider.setUserDetailsService(userDetailsService());
        inMemoryAuthenticationProvider.setPasswordEncoder(passwordEncoder());

        auth.authenticationProvider(inMemoryAuthenticationProvider);
    }
}

在上述示例中,我们配置了一个DaoAuthenticationProvider(数据库验证)和一个InMemoryAuthenticationProvider(内存验证)。如果第一个AuthenticationProvider对象无法验证通过,Spring Security会尝试通过第二个AuthenticationProvider验证。

4. 自定义登录成功后跳转的页面

我们可以使用defaultSuccessURL方法指定成功之后的跳转页面。示例代码如下:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
            .loginPage("/login").permitAll()
            .defaultSuccessUrl("/")
            .and()
            .logout().permitAll();
    }
}

在上述示例中,我们使用了defaultSuccessURL方法指定成功之后的跳转页面为根目录/。当登录成功之后,用户将会被跳转到根目录页面。

5. 登录成功之后返回JSON

我们可以将登录成功之后返回JSON数据,示例代码如下:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
            .successHandler((request, response, authentication) -> {
                response.setContentType("application/json;charset=UTF-8");
                PrintWriter out = response.getWriter();
                out.write("{\"status\":\"success\", \"msg\":\"登录成功\"}");
                out.flush();
                out.close();
            })
            .failureHandler((request, response, exception) -> {
                response.setContentType("application/json;charset=UTF-8");
                PrintWriter out = response.getWriter();
                out.write("{\"status\":\"error\", \"msg\":\"登录失败\"}");
                out.flush();
                out.close();
            });
    }
}

在上述示例中,我们将JSON数据写入到HttpServletResponse中,并通过setContentType方法设置了返回数据的类型为json。在登录失败的情况下,我们也执行了类似的操作。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot + Spring Security 基本使用及个性化登录配置详解 - Python技术站

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

相关文章

  • 详解如何使用java实现Open Addressing

    详解如何使用Java实现Open Addressing Open Addressing是一种哈希表的实现策略,它可以通过将元素插入到哈希表中直到找到一个为空的插槽。在此过程中,与元素对应的键的哈希值在哈希表中指定其插入的位置。Open Addressing的优点在于只需要一个数组来存储哈希表,而不需要使用链表。 本文将详细介绍如何使用Java实现Open A…

    Java 2023年5月26日
    00
  • Java模拟实现HTTP服务器项目实战

    Java模拟实现HTTP服务器项目实战攻略 简介 本攻略旨在帮助Java初学者或者对于Web开发有基础认识的人,利用Java模拟实现一个HTTP服务器。本攻略将涵盖以下内容:- HTTP协议简介- 建立Java Socket Server服务端- 解析HTTP请求报文- 构建HTTP响应报文 HTTP协议简介 HTTP(Hyper Text Transfer…

    Java 2023年5月19日
    00
  • SpringBoot分页的实现与long型id精度丢失问题的解决方案介绍

    针对SpringBoot分页的实现与long型id精度丢失问题的解决方案,我提供以下完整攻略: SpringBoot分页的实现 SpringBoot中分页的实现可以通过Pageable和Page进行操作。 1、Pageable Pageable是一个接口,我们可以通过PageRequest类来实例化这个接口。 Pageable pageable = Page…

    Java 2023年5月20日
    00
  • 使用java8的方法引用替换硬编码的示例代码

    当编写Java代码时,我们经常会使用硬编码方式来实现一些操作。而Java8引入的方法引用却可以使我们的代码更加简洁而且易于维护。下面是使用Java8的方法引用替换硬编码代码的完整攻略: 1. 什么是方法引用 方法引用是一种可以用来简化Lambda表达式的写法,可以用过已有的方法来引用类的实例或类静态方法。可以将方法引用看成是Lambda表达式的精简写法。 2…

    Java 2023年5月19日
    00
  • Mybatis执行流程、缓存原理及相关面试题汇总

    下面我会详细讲解Mybatis执行流程、缓存原理及相关面试题汇总。 Mybatis执行流程 Mybatis的执行流程大致可以分为以下几个步骤: 解析SqlMapConfig.xml文件,创建Configuration对象; 解析映射文件,创建MappedStatement对象; 创建SqlSessionFactory对象; 创建SqlSession对象; 使…

    Java 2023年5月20日
    00
  • java LeetCode刷题稍有难度的贪心构造算法

    Java LeetCode刷题稍有难度的贪心构造算法攻略 在LeetCode刷题过程中,贪心算法在构造类问题中经常发挥着非常强大的作用。本篇文章将介绍贪心构造算法的基本思想和常见的实现模式,并给出两个例题作为说明。 概述 贪心构造算法指的是在求解最优解的过程中,每一步都采取当前状态下最优的选择。该算法通常适用于满足贪心选择性质的问题中,即问题能够分解成若干个…

    Java 2023年5月26日
    00
  • JSP 获取spring容器中bean的两种方法总结

    介绍JSP和Spring容器 JavaServer Pages(JSP)是一种在服务器上使用的Java技术,用于创建动态Web页面。Spring容器是一个轻量级的Java开发框架,用于协调Java应用中的对象和实现应用程序中不同层之间的松耦合。 JSP获取Spring容器中Bean的两种方法 Spring容器中的Bean可以被JSP使用,JSP可以通过以下两…

    Java 2023年6月16日
    00
  • 送电子书福利啦!

    过去若干年,一边工作编程,一边思考提炼,写了一些关于“写整洁业务代码”的文章,在随笔分类“代码修行”下。有一天在公司文档空间分享时,突然想到:可以制作一本电子书,将过往的重要经验总结起来,也是对自己十年编程生涯的一个阶段性回顾,作为继续前进的阶梯。 我的第一本电子书 书名:《代码修行:一步一步写出整洁的业务代码》 链接: https://pan.baidu.…

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