首页 > 其他分享 >SpringSecurity如何自定义用户认证逻辑?

SpringSecurity如何自定义用户认证逻辑?

时间:2024-06-11 09:59:53浏览次数:8  
标签:自定义 springframework 认证 authentication import org security SpringSecurity

在 Spring Security 中自定义用户认证逻辑通常涉及到实现你自己的 UserDetailsService 或使用自定义的 AuthenticationProvider。下面是通过这两种方式自定义用户认证逻辑的基本演示:

使用 UserDetailsService 自定义

UserDetailsService 是 Spring Security 用于从数据库、LDAP 或其他任何地方检索用户信息的策略接口。你可以通过实现此接口来定义如何检索用户信息。

步骤 1: 实现 UserDetailsService

首先,创建一个实现 UserDetailsService 接口的类。你需要重写 loadUserByUsername 方法来定义加载用户的逻辑。

import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username)
            .orElseThrow(() -> new UsernameNotFoundException("User not found with username: " + username));

        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), 
                user.isEnabled(), true, true, true, getAuthorities(user.getRoles()));
    }

    private Collection<? extends GrantedAuthority> getAuthorities(Collection<Role> roles) {
        return roles.stream().map(role -> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toList());
    }
}

步骤 2: 配置 Spring Security 使用你的 UserDetailsService

在你的 Security 配置类中,你需要将 AuthenticationManager 配置为使用你的 CustomUserDetailsService

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomUserDetailsService userDetailsService;

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService);
        authProvider.setPasswordEncoder(new BCryptPasswordEncoder());
        return authProvider;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // http configuration...
    }

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

使用 AuthenticationProvider 自定义

如果你想拥有更多的控制权,比如处理更复杂的认证逻辑(例如 OTP、多因素认证等),你可以实现自定义的 AuthenticationProvider

步骤 1: 实现 AuthenticationProvider

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String password = authentication.getCredentials().toString();

        // 在这里添加自定义逻辑来验证用户名和密码
        if ("正确的逻辑检查") {
            // 如果验证成功,创建并返回一个 Authentication 实现类的实例
            return new UsernamePasswordAuthenticationToken(username, password, Collections.emptyList());
        } else {
            throw new BadCredentialsException("External system authentication failed");
        }
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}

步骤 2: 在你的 Security 配置中注册自定义 AuthenticationProvider

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(new CustomAuthenticationProvider());
}

通过使用 UserDetailsService 或实现 AuthenticationProvider,你可以轻松地将 Spring Security 集成到你的应用程序中,并根据需要定制认证逻辑。这为处理各种认证需求提供了灵活性和强大的控制能力。

标签:自定义,springframework,认证,authentication,import,org,security,SpringSecurity
From: https://blog.csdn.net/m0_68948067/article/details/139322829

相关文章

  • 自定义注解获取属性对应枚举的翻译值
    平时在开发的时候难免会遇到枚举来翻译类,于是写一个自定义注解来在开发的时候自动翻译枚举的值相关代码如下:@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Documented@JacksonAnnotationsInsidepublic@interfaceEnumShow{/***要转换......
  • python实现自定义线程池
    线程池ThreadPool对象的几个关键方法:get_idle_num():获得当前空闲线程的数量submit(task:callable):把一个任务(实际上就是一个函数)提交到线程池中执行.如果没有空闲线程则阻塞.wait_idle():阻塞,直到有空闲线程stop():停止线程池中的所有线程.(注意:非强制停止,......
  • 自定义类型:结构体
    目录1.结构体类型的声明1.1结构体1.1.1结构体如何声明1.1.2结构体变量的创建和初始化1.2结构的特殊声明1.3结构的自引用2.结构体内存对齐2.1对齐规则2.2为什么存在内存对齐?2.3修改默认对齐数3.结构体传参4.结构体实现位段 4.1什么是位段4.2位段的......
  • 基础概念-认证授权会话
    1.1.  什么是认证进入移动互联网时代,大家每天都在刷手机,常用的软件有微信、支付宝、头条等,下边拿微信来举例子说明认证相关的基本概念,在初次使用微信前需要注册成为微信用户,然后输入账号和密码即可登录微信,输入账号和密码登录微信的过程就是认证。系统为什么要认证?......
  • 《物料清单汇总查询》二开增加自定义字段
    业务需求增加文本,显示物料清单的替代编码。 说明BomQueryIntegration继承了BomQueryForward。具体步骤1、新建cs类BomQueryIntegrationExtend,继承BomQueryIntegration,重写获取子项信息GetBomChildData。protectedoverrideList<DynamicObject>GetBomChildData(List<Dynami......
  • python后端结合uniapp与uview组件tabs,实现自定义导航按钮与小标签颜色控制
    实现效果(红框内):后端api如下:@task_api.route('/user/task/states_list',methods=['POST','GET'])@visitor_token_requireddeftask_states(user):name_list=['待接单','设计中','交付中','已完成','......
  • C#自定义控件(自定义属性、自定义事件)
    1、创建类库项目在当前解决方案中添加新项目类库。注意选择“.NETFramework”创建完成后,删除默认的Class1类。2、添加项目图片在类库的debug中添加一个文件夹image,并复制项目需要的图片。3、把全部项目拖放到资源文件中选中所有图片,然后拖放到[资源],方法是右击类库项目......
  • 将stanfordcorenlp的tokenizer换成自定义的(或用stanfordcorenlp对自定义tokenizer分词
    本文是基于中文语料做的,对于英文语料应该也是同理,即同样适用的。分析stanfordcorenlp的分词结果,可以发现,它好像是对最小的中文词进行分词,即其对中文的分词粒度很小,这对于某些nlp场景可能就不太合适了,自然的就想到能不能将stanfordcorenlp中用于分词的tokenizer替换掉,替换成自......
  • 实战 | YOLOv10 自定义数据集训练实现车牌检测 (数据集+训练+预测 保姆级教程)
    导读    本文主要介绍如何使用YOLOv10在自定义数据集训练实现车牌检测(数据集+训练+预测保姆级教程)。  YOLOv10简介  YOLOv10是清华大学研究人员在UltralyticsPython包的基础上,引入了一种新的实时目标检测方法,解决了YOLO以前版本在后处理和模型架构方面的不足......
  • C语言笔记第12篇:自定义类型(struct结构体)
    1、结构体类型的声明为什么要有自定义的结构类型呢?这是因为稍微复杂的类型,直接使用内置类型是不行的!比如:描述一个人或 一本书的价格、版号等信息。1.1结构的创建结构体是一些值的集合,这些值称为成员变量,结构的每个成员可以是不同类型的变量。1.1.1 结构的声明structt......