Дайджест аутентификации с помощью Spring Security с использованием javaconfig

Итак, я пытаюсь создать пружину дайджест-аутентификации, следуя документация, пытающаяся перевести "требования" xml в требования Java.

Допустим, у нас есть xml, как в документах:

<bean id="digestFilter" class=
    "org.springframework.security.web.authentication.www.DigestAuthenticationFilter">
  <property name="userDetailsService" ref="jdbcDaoImpl"/>
  <property name="authenticationEntryPoint" ref="digestEntryPoint"/>
  <property name="userCache" ref="userCache"/>
</bean>

<bean id="digestEntryPoint" class=
    "org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint">
  <property name="realmName" value="Contacts Realm via Digest Authentication"/>
  <property name="key" value="acegi"/>
  <property name="nonceValiditySeconds" value="10"/>
</bean>

Это мой текущий javaconfig:

@Configuration
@Profile({"integration", "release"})
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
{

  @Resource(authenticationType = Resource.AuthenticationType.CONTAINER, mappedName = "jdbc/db")
  private DataSource datasource;

  @Override
  protected void registerAuthentication (AuthenticationManagerBuilder auth) throws Exception
  {
    auth.jdbcAuthentication().dataSource(datasource)
        .usersByUsernameQuery("SELECT ID_USER, PASSWORD, ACTIVE FROM USERS WHERE ID_USER = ?;")
        .authoritiesByUsernameQuery("SELECT ID_USER, ID_ROLE FROM USER_ROLES WHERE ID_USER = ?");
  }

  @Bean
  public BasicAuthenticationEntryPoint entryPoint ()
  {

    BasicAuthenticationEntryPoint basicAuthenticationEntryPoint = new BasicAuthenticationEntryPoint();
    basicAuthenticationEntryPoint.setRealmName("Basic WF Realm");
    return basicAuthenticationEntryPoint;
  }

  @Bean
  public DigestAuthenticationEntryPoint digestEntryPoint ()
  {
    DigestAuthenticationEntryPoint digestAuthenticationEntryPoint = new DigestAuthenticationEntryPoint();
    digestAuthenticationEntryPoint.setKey("mykey");
    digestAuthenticationEntryPoint.setRealmName("Digest WF Realm");
    return digestAuthenticationEntryPoint;
  }

  public DigestAuthenticationFilter digestAuthenticationFilter (
      DigestAuthenticationEntryPoint digestAuthenticationEntryPoint)
  {
    DigestAuthenticationFilter digestAuthenticationFilter = new DigestAuthenticationFilter();
    digestAuthenticationFilter.setAuthenticationEntryPoint(digestEntryPoint());
//    digestAuthenticationFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
    return digestAuthenticationFilter;
  }

  @Override
  protected void configure (HttpSecurity http) throws Exception
  {
        // basic auth - it works!
        // http.exceptionHandling().authenticationEntryPoint(entryPoint()).and()
    http            
    .authorizeUrls().antMatchers("/firstres/*").permitAll()
        .antMatchers("/secondres/*").permitAll()
        .antMatchers("/resources/*").permitAll()
        .antMatchers("/**").hasAnyAuthority("first_role", "second_role").and()//.httpBasic();
    .addFilter(digestAuthenticationFilter(digestEntryPoint()));
  }

}

Я просто получаю 403 - Отказано в доступе. С httpBasic работал. Можете ли вы сказать, что мне не хватает?


person dierre    schedule 13.08.2013    source источник
comment
Не используйте дайджест-аутентификацию. Начнем с того, что его безопасность слаба, но, что наиболее важно, он требует, чтобы сервер хранил пароли как есть (если ваш сервер скомпрометирован, злоумышленник может войти в систему как любой пользователь).   -  person rustyx    schedule 09.07.2016


Ответы (1)


Я не уверен, когда вы получаете отказ в доступе 403, но если это происходит, когда вы запрашиваете защищенный ресурс до аутентификации, вам нужно следующее:

@Override
protected void configure (HttpSecurity http) throws Exception
{
  http
      .exceptionHandling()
          // this entry point handles when you request a protected page and
          // you are not yet authenticated
          .authenticationEntryPoint(digestEntryPoint())
          .and()
      .authorizeUrls()
          .antMatchers("/firstres/*").permitAll()
          .antMatchers("/secondres/*").permitAll()
          .antMatchers("/resources/*").permitAll()
          .antMatchers("/**").hasAnyAuthority("first_role", "second_role").and()
      // the entry point on digest filter is used for failed authentication attempts
      .addFilter(digestAuthenticationFilter(digestEntryPoint()));
}

@Override
@Bean
public UserDetailsService userDetailsServiceBean() {
    return super.userDetailsServiceBean();
}

public DigestAuthenticationFilter digestAuthenticationFilter (
    DigestAuthenticationEntryPoint digestAuthenticationEntryPoint)
{
  DigestAuthenticationFilter digestAuthenticationFilter = new DigestAuthenticationFilter();
  digestAuthenticationFilter.setAuthenticationEntryPoint(digestEntryPoint());
  digestAuthenticationFilter.setUserDetailsService(userDetailsServiceBean());
  return digestAuthenticationFilter;
}
person Rob Winch    schedule 14.08.2013
comment
Привет Роб. С вашим кодом у меня появляется всплывающее окно для доступа, но когда я это делаю, я получаю исключение NullPointerException на org.springframework.security.web.authentication.www.DigestAuthenticationFilter.doFilter(DigestAuthenticationFilter.java:144). Это userDetailService.loadByUsername. Если вы видите мой код, это закомментированная часть. Что я должен передать setAuthenticationDetailsSource? - person dierre; 14.08.2013
comment
Это не AuthenticationDetailsSource, это UserDetailsService. Вам нужно переопределить метод userDetailsServiceBean и представить его как bean-компонент. Затем вы можете указать его в своей конфигурации. Подробности смотрите в моих обновлениях - person Rob Winch; 14.08.2013