API 基本认证

问题描述 投票:0回答:2

我的应用程序有基于 spring 3 xml 的配置。 我正在从 Postman 调用 REST API(不是基于表单的登录),并在授权标头中使用用户名密码。 对于身份验证,我创建了实现 AuthenticationProvider 的身份验证提供程序。

    <security:authentication-manager>
            <security:authentication-provider ref="restAuthentication"/>
    </security:authentication-manager>

问题是如何在自定义身份验证提供程序中获取凭据? AuthenticationProvider 不会在重写身份验证方法中提供带有标头的身份验证请求。


或者,我尝试扩展 BasicAuthenticationEntryPoint,但在 afterPropertiesSet() 方法之后运行应用程序时出现错误。

    @Override
    public void afterPropertiesSet() throws Exception {
        setRealmName("Spring");
        super.afterPropertiesSet();
    }

创建名称为“org.springframework.security.authenticationManager”的bean时出错:通过构造函数参数0表达的依赖关系不满足:无法将类型[java.util.ArrayList]的参数值转换为所需类型[java.util.List]:失败将“java.util.ArrayList”类型的值转换为所需类型“java.util.List”。

请建议这两种方式中哪一种合适,以及如何解决冲突。

spring spring-security spring-3
2个回答
0
投票

从请求中检索凭据并将其发送到

AuthenticationManager
的责任通常来自
Filter
,请参阅
BasicAuthenticationFilter

也就是说,您可能需要一个过滤器或控制器端点,将

HttpServletRequest
转换为
Authentication
对象,并将该对象传递给自动装配的
AuthenticationManager


0
投票

这是我的解决方案:

安全配置

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
    private BasicAuthManager basicAuthManager;

    @Autowired
    public SecurityConfiguration(BasicAuthManager basicAuthManager) {
        this.basicAuthManager = basicAuthManager;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

        return http
            .csrf(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests(requests -> requests
                    .anyRequest().authenticated())
            .authenticationManager(basicAuthManager)
            .httpBasic(withDefaults())
            .build();
     }
}

基本身份验证管理器

@Service
public class BasicAuthManager implements AuthenticationManager {
    private final UserDetailsService userDetailsService;
    private final PasswordEncoder passwordEncoder;

    @Autowired
    public BasicAuthManager(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
        this.userDetailsService = userDetailsService;
        this.passwordEncoder = passwordEncoder;
    }

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

        try {
            user = userDetailsService.loadUserByUsername(username);
        } catch (UsernameNotFoundException ex) {
            throw new BadCredentialsException("User does not exists");
        }

        if (StringUtils.isBlank(password) || !passwordEncoder.matches(password, user.getPassword())) {
            throw new BadCredentialsException("Password is wrong");
        }

        return new UsernamePasswordAuthenticationToken(username, null, user.getAuthorities());
    }
}

安全Beans

@Configuration
public class SecurityBeans {
    @Value("${my.security.username}")
    private String username;
    @Value("${my.security.password}")
    private String password;
    @Value("${my.security.userRole}")
    private String userRole;

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

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails userDetails = User
                .withUsername(username)
                .password(passwordEncoder().encode(password))
                .roles(userRole)
                .build();

        return new InMemoryUserDetailsManager(userDetails);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.