Spring Security 自定义认证

简介: Spring Security 自定义认证

角色说明

  • CustomAuthenticationFilter:构建Token类并交给AuthenticationProvider进行验证,继承自AbstractAuthenticationProcessingFilter,AbstractAuthenticationProcessingFilter为UsernamePasswordAuthenticationFilter的父类,封装了登陆过程用到的常用内容及方法.也可以不继承此类完核心功能即可.
  • CustomAuthenticationProvider:对支持的token进行校验与shiro中Realm类似,区别是Security将授权与认证合并了.
  • CustomAuthenticationToken:自定义token,存储自定义内容,程序中使用SecurityContextHolder.getContext().getAuthentication()来获取

java配置

过滤器配置

public class CustomAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
    public CustomAuthenticationFilter() {
        super(new AntPathRequestMatcher("/custom/**"));
        //
        setContinueChainBeforeSuccessfulAuthentication(true);
    }
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        CustomAuthenticationToken authentication = null;
        try {
            Enumeration<String> headers = request.getHeaders("secretKey");
            String secretKey = headers.nextElement();
            // 通过request中参数构建自定义token,与CustomAuthenticationProvider对应即可
            authentication = new CustomAuthenticationToken(secretKey, secretKey);
            //设置附属信息,sessionid,ip
            setDetails(request, authentication);
            //通过Provider验证token
            authentication = (CustomAuthenticationToken) getAuthenticationManager().authenticate(authentication);
            //
            SecurityContextHolder.getContext().setAuthentication(authentication);
        } catch (Exception e) {
            throw new AuthenticationServiceException("secretKey认证失败",e);
        }
        return authentication;
    }
    protected void setDetails(HttpServletRequest request,
                              CustomAuthenticationToken authRequest) {
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
    }
}

说明

  • 此示例是在请求头中增加参数用于认证,并没有后续的登陆成功处理所以设置了setContinueChainBeforeSuccessfulAuthentication
  • setContinueChainBeforeSuccessfulAuthentication设置为true表示认证成功之后进入后续过滤,不走后续的登陆成功处理
  • 需要手动将认证结果存入SecurityContextHolder中避免后续拿不到认证信息.

Provider 配置

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String secretKey = (String) authentication.getCredentials();
        //自定义校验逻辑
        if(!"123".equals(secretKey)){
            throw new InsufficientAuthenticationException("认证错误");
        }
        Set<String> dbAuthsSet = new HashSet<String>();
        dbAuthsSet.add("customUser");
        Collection<? extends GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(dbAuthsSet.toArray(new String[0]));
        return new CustomAuthenticationToken(secretKey, secretKey, authorities);
    }
    @Override
    public boolean supports(Class<?> authentication) {
        return CustomAuthenticationToken.class.isAssignableFrom(authentication);
    }
}

SecurityConfig配置

@Order(2)
@Configuration
public class CustomSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private CustomAuthenticationProvider customAuthenticationProvider;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .antMatcher("/custom/**")
                .addFilterBefore(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER)
                .and().authorizeRequests().antMatchers("/custom/**").authenticated();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(customAuthenticationProvider);
    }
    @Bean
    public CustomAuthenticationFilter customAuthenticationFilter() throws Exception {
        CustomAuthenticationFilter filter = new CustomAuthenticationFilter();
        filter.setAuthenticationManager(super.authenticationManagerBean());
        return filter;
    }
}

相关代码

https://gitee.com/MeiJM/spring-cram/tree/master/customSecurity 中CustomSecurityConfig相关部分

目录
相关文章
|
11天前
|
JSON 安全 Java
什么是JWT?如何使用Spring Boot Security实现它?
什么是JWT?如何使用Spring Boot Security实现它?
47 5
|
2月前
|
安全 Java 数据库
安全无忧!在 Spring Boot 3.3 中轻松实现 TOTP 双因素认证
【10月更文挑战第8天】在现代应用程序开发中,安全性是一个不可忽视的重要环节。随着技术的发展,双因素认证(2FA)已经成为增强应用安全性的重要手段之一。本文将详细介绍如何在 Spring Boot 3.3 中实现基于时间的一次性密码(TOTP)双因素认证,让你的应用安全无忧。
114 5
|
4月前
|
SQL Java 测试技术
在Spring boot中 使用JWT和过滤器实现登录认证
在Spring boot中 使用JWT和过滤器实现登录认证
262 0
|
1天前
|
安全 Java 数据安全/隐私保护
基于内存认证的 Spring Security
通过本文的介绍,希望您能够深入理解基于内存认证的Spring Security配置与使用方法,并能够在实际开发中灵活应用这一技术,提升应用的安全性和用户体验。
22 9
|
16天前
|
JSON 安全 算法
Spring Boot 应用如何实现 JWT 认证?
Spring Boot 应用如何实现 JWT 认证?
45 8
|
15天前
|
安全 Java 应用服务中间件
如何将Spring Boot应用程序运行到自定义端口
如何将Spring Boot应用程序运行到自定义端口
26 0
|
4月前
|
Java Spring
【Azure Spring Cloud】Spring Cloud Azure 4.0 调用Key Vault遇见认证错误 AADSTS90002: Tenant not found.
【Azure Spring Cloud】Spring Cloud Azure 4.0 调用Key Vault遇见认证错误 AADSTS90002: Tenant not found.
|
4月前
|
Java 数据安全/隐私保护 Spring
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效
|
4月前
|
JSON 安全 Java
|
4月前
|
Java Spring 安全
Spring 框架邂逅 OAuth2:解锁现代应用安全认证的秘密武器,你准备好迎接变革了吗?
【8月更文挑战第31天】现代化应用的安全性至关重要,OAuth2 作为实现认证和授权的标准协议之一,被广泛采用。Spring 框架通过 Spring Security 提供了强大的 OAuth2 支持,简化了集成过程。本文将通过问答形式详细介绍如何在 Spring 应用中集成 OAuth2,包括 OAuth2 的基本概念、集成步骤及资源服务器保护方法。首先,需要在项目中添加 `spring-security-oauth2-client` 和 `spring-security-oauth2-resource-server` 依赖。
57 0