当前位置: 首页 > 知识库问答 >
问题:

Spring Security,Boot:替换默认的

丁雅懿
2023-03-14

我试图在登录过程中添加用户ip验证。如果用户的ip地址不在数据库中,应用程序应该拒绝身份验证。

问题:根据下面的设置,Auth.AuthenticationProvider()并没有替换默认的DaoAuthenticationProvider,而是将UserIpAuthenticationProvider添加为列表中的第一个AuthenticationProvider。

在用户名/密码组合不正确的情况下,框架最终调用UserDetailsService.loadUserbyUserName()两次,一次来自UserIpAuthenticationProvider,另一次来自内部DaoAuthenticationProvider,它抛出最后的BadCredentialsException()。

问题是:在Spring Boot中是否可以设置任何设置,以便Spring Security不添加它自己的内部实例DaoAuthenticationProvider,而只使用我的UserIpAuthenticationProvider,它已经具有所有必要的功能(可能通过某种方式替换AuthenticationManagerBuilder来覆盖userDetailsService()方法)。

public <T extends UserDetailsService> DaoAuthenticationConfigurer<AuthenticationManagerBuilder,T> userDetailsService(
        T userDetailsService) throws Exception {
    this.defaultUserDetailsService = userDetailsService;
    return apply(new DaoAuthenticationConfigurer<AuthenticationManagerBuilder,T>(userDetailsService));
}

配置:根据我的理解,UserDetailsService应该提供有关用户的所有必要细节,以便AuthenticationProvider能够决定身份验证是否成功。

由于所有必要的信息都是从数据库加载的,因此很自然地扩展了DaoAuthenticationProvider并在overriden additionalAuthenticationChecks()方法中添加了一个额外的验证(白名单IP列表位于数据库中,因此它们作为IpAwareUser中用户对象的一部分加载)。

@Named
@Component
class UserIpAuthenticationProvider  extends DaoAuthenticationProvider {
    @Inject
    public UserIpAuthenticationProvider(UserDetailsService userDetailsService)
    {
        ...
    }

    @SuppressWarnings("deprecation")
    protected void additionalAuthenticationChecks(UserDetails userDetails,
                                                  UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        super.additionalAuthenticationChecks(userDetails, authentication);

        WebAuthenticationDetails details = (WebAuthenticationDetails) authentication.getDetails();
        IpAwareUser ipAwareUser = (IpAwareUser) userDetails;
        if (!ipAwareUser.isAllowedIp(details.getRemoteAddress()))
        {
            throw new DisabledException("Login restricted from ip: " + details.getRemoteAddress());
        }
    }
}

这将被注入到SecurityConfiguration中:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilter(authenticationFilter);

        http.authorizeRequests()
                .antMatchers("/", "/javascript/**", "/css/**").permitAll()
                .antMatchers("...").access("...")
                .anyRequest().authenticated()
                .and().formLogin().loginPage("/").permitAll()
                .and().logout().invalidateHttpSession(true).deleteCookies("JSESSIONID").permitAll()
                .and().csrf().disable()
        ;
    }

    @Inject
    private UserDetailsService userDetailsService;

    @Inject
    private UserIpAuthenticationProvider userIpAuthenticationProvider;


    @Inject
    private JsonUsernamePasswordAuthenticationFilter authenticationFilter;

    @Bean
    public JsonUsernamePasswordAuthenticationFilter authenticationFilter() {
        return new JsonUsernamePasswordAuthenticationFilter();
    }

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

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public AuthenticationSuccessHandler authenticationSuccessHandler() throws Exception {
        return new JsonAuthenticationSuccessHandler();
    }

    @Bean
    public AuthenticationFailureHandler authenticationFailureHandler() throws Exception {
        return new JsonAuthenticationFailureHandler();
    }
}
@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackageClasses = {SecurityConfiguration.class, DataController.class, DaoService.class})
public class Application extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application;
    }
}

共有1个答案

蒋航
2023-03-14

定义自己的DaoAuthenticationProvider

@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() {
    return new UserIpAuthenticationProvider();
}

应该替换Spring Boot默认实例(bean类型不是DaoAuthenticationProvider或UserIpAuthenticationProvider)

 类似资料:
  • 我只是想知道有没有什么方法可以为log4j中的属性替换提供默认值呢? 我想在Java系统属性中传递文件路径,然后与“${env:MySystemProperty}”一起使用。但如果开发人员忘记设置此属性怎么办?那么我希望在log4j2.xml中定义一些有意义的默认值。 你知道如何实现这个功能吗? 编辑: 环境替换对我不起作用: standalone.conf log4j2.xml 我可以在wild

  • 问题内容: 是否可以替换WCF的默认JSON序列化(我目前正在测试行为),并作为MIME类型传递。特别是,我不喜欢默认情况下每个属性都是键/值对,例如: 我仅将服务用于启用JSON的端点(使用jQuery + WCF请求数据)。 问题答案: 您可以使用消息格式化程序来更改用于处理JSON的序列化程序。https://docs.microsoft.com/zh- cn/archive/blogs/c

  • 我正在尝试替换默认的android电话呼叫应用程序。更具体地说,我希望在每次执行呼叫操作时启动我的自定义电话呼叫屏幕。

  • 我想把系统默认的表情符号转换成Twitter的表情符号。我在我的web应用程序中实现了一个emoji选择器,当我从emoji托盘中选择任何emoji时,该emoji将基于系统操作系统出现在文本区中。如果我使用windows,那么emoji就会出现在基于windows的文本区中,如果我使用Linux,那么它就会出现在基于Linux的文本区中。 但我想要的是,无论操作系统如何,Twitter表情符号都

  • 我想用我自己的图像替换Android Maps V2用于“我的位置”的默认图标。我创建了自己的平铺提供程序,它带来了一些以蓝色为主的地图,因此默认的我的位置图标,小蓝色箭头,很难看到。 以前我只会重写的draw方法,但是新API中似乎没有。 我还需要图标能够旋转,就像箭头所做的那样,取决于你所面对的方向。所以我不能只用普通的记号笔。基本上,我只需要为那个箭头创建一个自定义图像。

  • 本文向大家介绍SpringBoot2使用Jetty容器操作(替换默认Tomcat),包括了SpringBoot2使用Jetty容器操作(替换默认Tomcat)的使用技巧和注意事项,需要的朋友参考一下 Jetty和tomcat的比较 Tomcat和Jetty都是一种Servlet引擎,他们都支持标准的servlet规范和JavaEE的规范。 架构比较 Jetty的架构比Tomcat的更为简单 Jet