【问题标题】:In a specific path use username/password authentication在特定路径中使用用户名/密码身份验证
【发布时间】:2019-09-18 01:42:02
【问题描述】:

我有一个配置了工作安全性的 spring 项目,我想要做的是设置一个特定的路径,该路径将接受 REST 调用,只需要基本的用户/密码身份验证,可以硬编码。

我知道这有点奇怪,但我有一个非常具体的用例。

安全码类似于:

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
        ...
        .and()
            .authorizeRequests()
            .antMatchers("my-path/**").authenticated()
    }

我不太了解 spring 是如何发挥所有魔力的,但我希望它看起来像这样:

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
        ...
        .and()
            .authorizeRequests()
            .antMatchers("my-path/**").authenticatedWithUserPassword("user", "pswd")
    }

必须发生的两件事:

  • 我希望这个用户/pswd 只为这条路径工作!
  • 我希望此路径仅适用于该用户/pswd,而不适用于其他身份验证类型!

【问题讨论】:

  • 您的 API 中有其他身份验证类型吗?
  • 是的,通常我的应用受 oauth2 保护
  • 有人刚刚引用了我这个:stackoverflow.com/questions/25794680/…,看来这可能是要走的路
  • @orirab:常规方式是使用两种Spring Security配置,一种只匹配你的特殊路径(这个配置需要低位),一种匹配所有路径。您可以在第一个 Spring Security 配置中使用本地内存中的身份验证管理器,而不是使用全局身份验证管理器。
  • @dur 你能提供一个代码示例吗?

标签: java spring spring-boot spring-security


【解决方案1】:

好的,所以我做了一点修改(受this answer 启发),但它为我解决了问题。

首先,我创建了这个AuthenticationProvider

public class ClusterInternalAuthenticationProvider implements AuthenticationProvider {

    public static final String USER = "...";
    public static final String PASSWORD = "...";

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken)authentication;

        Object principal = token.getPrincipal();
        Object credentials = token.getCredentials();

        if (principal.equals(USER) && credentials.equals(PASSWORD)) {
            return new UsernamePasswordAuthenticationToken(
                principal,
                credentials,
                Collections.singletonList(new SimpleGrantedAuthority("RELEVANT_AUTHORITY"))
            );
        }

        throw new BadCredentialsException("Sorry mate, wrong credentials...");
    }

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

这会尝试 user/pswd 组合,如果 true 返回具有我访问特定路径所需的权限的凭据。

接下来,在 SecurityConfiguration 中启用httpBasic 并添加我的AuthenticationProvider

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
        ...
        .and()
            .authorizeRequests()
            .antMatchers("my-path/**").hasAuthority("RELEVANT_AUTHORITY")
        .and()
            .httpBasic()
        .and()
            .authenticationProvider(new ClusterInternalAuthenticationProvider());
    }

这似乎足够了,但不是一个“正确”的修复,因为我需要确保不要在其他地方使用此权限,而且对于如此小的需求来说它似乎过度 - 非常欢迎其他解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-27
    • 2019-08-26
    • 2020-10-10
    • 2018-07-13
    • 1970-01-01
    • 2021-06-30
    • 1970-01-01
    • 2017-07-31
    相关资源
    最近更新 更多