如何使用 oauth2 grant_type=password 监听登录失败/成功

Posted

技术标签:

【中文标题】如何使用 oauth2 grant_type=password 监听登录失败/成功【英文标题】:How to listen login fail / success with oauth2 grant_type=password 【发布时间】:2016-11-14 17:19:41 【问题描述】:

我的应用使用 spring cloud oauth2 rest 和 angular 。

我的目标是使用spring server来限制登录失败的最大次数

angular2登录代码:

const body = "username=" + encodeURI(username) + "&password=" + encodeURI(password) +
      "&grant_type=password&client_id=" + encodeURI(this.clientId);

this.http.post("/oauth/token",body,headers:authHeaders).map
...

spring auth-server 网络安全代码:

    @Override
      protected void configure(HttpSecurity http) throws Exception 

        http.httpBasic().and().sessionManagement()
              .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
              .and().authorizeRequests()
            .anyRequest().authenticated();
      

我尝试了这两个事件:

public class AuthenticationFailureListener
    implements ApplicationListener<AuthenticationFailureBadCredentialsEvent>
@Override
  public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent e) 
  //...


和:

public class AuthenticationSuccessListener
    implements ApplicationListener<AuthenticationSuccessEvent> 
  @Override
  public void onApplicationEvent(AuthenticationSuccessEvent e) 
//...


但它不起作用

如何收听“登录失败和成功”?

【问题讨论】:

【参考方案1】:

Spring Security 将默认发布AuthenticationFailureBadCredentialsEvent(登录失败)事件。

您需要用 ApplicationEventPublisher覆盖 DefaultAuthenticationEventPublisher。

这必须在您的 Authentication Configuration 类中完成,如下所示。

@Configuration
protected static class MyAuthenticationConfiguration extends
        GlobalAuthenticationConfigurerAdapter 

    @Value("$ldap.url")
    String url;

    @Value("$ldap.base")
    String base;

    @Value("$ldap.managerDn")
    String managerDn;

    @Value("$ldap.password")
    String password;

    @Autowired
    ApplicationEventPublisher applicationEventPublisher;


    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception 
        auth.ldapAuthentication().userSearchFilter("sAMAccountName=0")
                .userSearchBase(base).contextSource().url(url)
                .managerDn(managerDn).managerPassword(password);
        //This publisher will trigger AuthenticationFailureBadCredentialsEvent (AbstractAuthenticationFailureEvent)
        auth.authenticationEventPublisher(new DefaultAuthenticationEventPublisher(applicationEventPublisher));

    

要支持基于表单的身份验证,请将以下内容添加到您的 configure() 方法中。

.and().formLogin();

整个配置方法应该类似于下面。

@Override
protected void configure(HttpSecurity http) throws Exception 

http.authorizeRequests().antMatchers("/css/**").permitAll()
        .anyRequest().fullyAuthenticated().and().formLogin();
super.configure(http);


【讨论】:

LDAP 身份验证只是身份验证管理器的示例。您可以使用内存或 jdbc 身份验证。

以上是关于如何使用 oauth2 grant_type=password 监听登录失败/成功的主要内容,如果未能解决你的问题,请参考以下文章

OAuth2.0/OIDC 中的 grant_type 与 response_type

oauth2错误AADSTS90014:请求正文必须包含以下参数:'grant_type'

Grails oAuth2 Provider 插件不对 grant_type 'password' 进行身份验证

OAuth 2身份验证中grant_type参数的目的是啥

google oauth2 grant_type=authorization_code 返回处理 OAuth 2 请求时出错

具有多个grant_type的Spring Oauth2授权服务器用户信息端点不起作用