【问题标题】:Spring Boot - Security - How to add pre authentication rules in authentication workflowSpring Boot - 安全 - 如何在身份验证工作流程中添加预身份验证规则
【发布时间】:2017-11-15 00:21:05
【问题描述】:

我正在运行一个使用 OAuth2 保护的 Spring Boot REST API。

这是我对访问令牌和刷新令牌的要求的实际工作 100% 配置:

@Configuration
public class ServerSecurityConfig extends GlobalAuthenticationConfigurerAdapter {

    @Autowired
    CustomPasswordEncoder passwordEncoder;

    @Autowired
    CustomUserDetailsService userDetailsService;

    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception {        
        auth
            .userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder);
    }
}

我现在需要添加一个预认证配置,所以登录它只有在某些配置可用时才可用。

我很困惑是否需要覆盖 AuthenticationManagerAuthenticationProvider

我尝试在上面的同一个类中添加这样的 CustomAuthenticationProvider:

@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
    // @formatter:off
    auth
        .authenticationProvider(authProvider)
        .userDetailsService(userDetailsService)
        .passwordEncoder(passwordEncoder);
    // @formatter:on
}

然后:

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        if (allowLogin()) {
            // Should call the UserDetailService as normally workflow.
            return null;
        }
        throw new AuthenticationServiceException("Out of service");
    }

    private boolean allowLogin() {
        //Custom logic            
        return false;
    }

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

但是当我抛出异常时,无论如何都会触发我的 UserDetailService。所以这不是一个选项,或者我可能以错误的方式实施。

实现 CustomAuthenticationManager 怎么样?我不知道在哪里调用它。

我试图避免在 UserDetailService 的 loadByUsername 方法中引发异常,因为如果有人已经获得令牌,那么他仍然可以使用我的 API。也许我必须在两个进程中创建逻辑?

更新

我认为我需要做的是添加一个CustomAccessDecisionVoter,但不知道在哪里为资源服务器配置。

【问题讨论】:

    标签: spring authentication spring-boot spring-security


    【解决方案1】:

    您是否考虑过编写自定义 userDetailsS​​ervice 来装饰当前的 UserDetailsS​​ervice 并覆盖 loadUserByUsername 方法并返回带有“ANONYMOUS”角色的 UserDetails 并且不允许具有该角色的用户访问您的应用

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserDetails user = userRolesManager.loadUserByUsername(username);
        if(allowLogin()){
            return user;
        }else{
            return new User(username, "notUsed", true, true,true,true, AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"));
        }
    }
    

    【讨论】:

    • 但是如果你已经登录了呢?记住我使用的是 Oauth2,所以如果你有一个令牌,你就不会再通过那个方法了......
    • 我在 OAuth 方面没有太多经验。但我猜你需要一个过滤器。类似OAuth2AuthenticationProcessingFilter
    • @FernandoFradegrada:如果您的自定义 AuthenticationProvider 被调用,AFAIK 您的自定义 UserDetailsService 只会被调用。因此,在哪里实现 Exception 并没有什么区别。在这两种情况下,您仍然可以使用您的 OAuth2 令牌。
    • 所以这是我的问题。我只需要在预定时间窗口之间授予访问权限。例如,“你只能在上午 9 点到晚上 9 点登录或访问资源,而我对如何实现这一点很生气..
    猜你喜欢
    • 1970-01-01
    • 2019-02-21
    • 2017-07-30
    • 2019-01-20
    • 2016-03-06
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 2020-07-30
    相关资源
    最近更新 更多