2014-11-14 4 views
1

У меня недавно создали приложение jhipster со следующим .yo-rc.jsonКроме маркеров аутентификации на основе, позволяет REST API конечной точку с базовой HTTP-аутентификация

{ 
    "generator-jhipster": { 
    "baseName": "cmpayments", 
    "packageName": "au.com.cmx.myapp", 
    "packageFolder": "au/com/cmx/myapp", 
    "authenticationType": "token", 
    "hibernateCache": "no", 
    "clusteredHttpSession": "no", 
    "websocket": "no", 
    "databaseType": "sql", 
    "devDatabaseType": "postgresql", 
    "prodDatabaseType": "postgresql", 
    "useCompass": false, 
    "buildTool": "maven", 
    "frontendBuilder": "gulp", 
    "javaVersion": "8" 
    } 
} 

Мне нравится, аутентификация на основе знамения на webapp, но я хотел бы, чтобы сервер выставлял REST api-вызов только с помощью HTTP-аутентификации. Некоторое время я сражался, но я совершенно не знаком с весенней безопасностью, и я надеюсь, что кто-то уже это сделал и может мне помочь.

Я попробовал следующее решение здесь: Basic and form based authentication with Spring security Javaconfig

Я создал вторую конфигурацию с @Order (1) в SecurityConfiguration.java как так

@Configuration 
@Order(1) 
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { 


    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.inMemoryAuthentication().withUser("api").password("pass").roles("API"); 
    } 

    protected void configure(HttpSecurity http) throws Exception { 
     http 
      .csrf() 
      .disable() 
      .authorizeRequests() 
      .antMatchers("/basicAuthApi/**").hasRole("API") 
      .and() 
      .httpBasic(); 
    } 
} 

Это работает. Если я попал в конечную точку под/basicAuthApi с чем-то другим, кроме api/pass credentials, я получаю 401. Yay.

Однако после этого, когда я вхожу в систему webapp как admin/admin (или пользователь/пользователь), я вошел в систему как anonymousUser. Если я прокомментирую дополнительную @Configuration в SecurityConfiguration.java и перезапустил приложение, эта проблема исчезнет, ​​и я правильно зарегистрируюсь в качестве администратора (или пользователя).

Интересно, что я попытался изменить порядок второй @Configuration на @Order (101), потому что я увидел где-то в одном из базовых классов @Order (100). В этом случае администратор и пользователь входят в систему при работе с webapp. Но оставшийся вызов api больше не защищен, и он преуспевает даже с неправильным паролем.

Кто-нибудь знает, что я делаю неправильно?

Благодаря dalyc

ответ

0

интро о порядке первым: По умолчанию порядка, если не указан, является самым большим возможным числом, которое отображает до минимально возможного приоритета (с более низким порядком приводит к более высокому приоритету). Поэтому, когда вы добавили конфигурацию с порядком = 1, у вас было две конфигурации: новая с порядком = 1 с более высоким приоритетом и сначала была проверена.

В сценарии описывается, где существуют обе конфигурации: Вы пытаетесь выполнить вход в webapp как admin/admin (или пользователь/пользователь), но весенняя проверка безопасности сначала включает конфигурацию с порядком = 1, которая имеет муравейник " .antMatchers("/basicAuthApi/**").hasRole("API")". Очевидно, это не совпадает с URL-адресом, который вы указываете, для сайта, но безопасность не сбой, потому что вам не хватает .anyRequest().authenticated(), что необходимо для того, чтобы сделать проверку безопасности фактически неудачной для пользователей, которые не прошли аутентификацию. Без этого вы действительно проходите проверку безопасности, хотя вы не аутентифицированы, то есть вы считаетесь анонимным пользователем с анонимным доступом пользователя. Поскольку весенняя безопасность для этой конфигурации преуспела, она даже не проверяет другую, связанную с веб-сайтом.

0

Я нашел решение, которое работает для меня. Я понял, что мне не нужна другая @Configuration, потому что конфигурация jhipster по умолчанию не перенаправляется на страницу входа для неавторизованного доступа - она ​​возвращает 401, который я тоже хочу для REST api. Так что я только что зарегистрировался пользователь с именем пользователя и пароль, которые я хочу использовать для API REST и добавил следующую строку в нижней части метода конфигурирования в

OAuth2ServerConfiguration.ResourceServerConfiguration

  `.antMatchers("/basicAuthApi/**").hasAuthority(AuthoritiesConstants.USER).and().httpBasic();` 

Я буду теперь попробуйте улучшить это, создав роль API и предоставив эту роль пользователям, которым необходимо вызвать REST API.

Я все еще хотел бы знать, почему моя первоначальная попытка возникла с этими проблемами, если кто-нибудь знает.

Приветствие dalyc

2

Замените оригинальный SecurityConfiguration.configure:

http 
     .csrf() 
     .ignoringAntMatchers("/websocket/**") 
    .and() 
     .addFilterAfter(new CsrfCookieGeneratorFilter(), CsrfFilter.class) 
     .exceptionHandling() 
     .authenticationEntryPoint(authenticationEntryPoint) 
    .and() 
     .rememberMe() 
     .rememberMeServices(rememberMeServices) 
     .rememberMeParameter("remember-me") 
     .key(env.getProperty("jhipster.security.rememberme.key")) 
    .and() 
     .formLogin() 
     .loginProcessingUrl("/api/authentication") 
     .successHandler(ajaxAuthenticationSuccessHandler) 
     .failureHandler(ajaxAuthenticationFailureHandler) 
     .usernameParameter("j_username") 
     .passwordParameter("j_password") 
     .permitAll() 
    .and() 
     .logout() 
     .logoutUrl("/api/logout") 
     .logoutSuccessHandler(ajaxLogoutSuccessHandler) 
     .deleteCookies("JSESSIONID") 
     .permitAll() 
    .and() 
     .headers() 
     .frameOptions() 
     .disable() 
    .and() 
     .authorizeRequests() 
     .antMatchers("/api/register").permitAll() 
     .antMatchers("/api/activate").permitAll() 
     .antMatchers("/api/authenticate").permitAll() 
     .antMatchers("/api/account/reset_password/init").permitAll() 
     .antMatchers("/api/account/reset_password/finish").permitAll() 
     .antMatchers("/api/logs/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/api/**").authenticated() 
     .antMatchers("/metrics/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/health/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/trace/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/dump/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/shutdown/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/beans/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/configprops/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/info/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/autoconfig/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/env/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/trace/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/api-docs/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/protected/**").authenticated(); 

этим одним:

http 
     .csrf() 
     .ignoringAntMatchers("/websocket/**") 
    .and() 
     .csrf() 
     .ignoringAntMatchers("/basicAuthApi/**") 
    .and() 
     .addFilterAfter(new CsrfCookieGeneratorFilter(), CsrfFilter.class) 
     .exceptionHandling() 
     .authenticationEntryPoint(authenticationEntryPoint) 
    .and() 
     .rememberMe() 
     .rememberMeServices(rememberMeServices) 
     .rememberMeParameter("remember-me") 
     .key(env.getProperty("jhipster.security.rememberme.key")) 
    .and() 
     .formLogin() 
     .loginProcessingUrl("/api/authentication") 
     .successHandler(ajaxAuthenticationSuccessHandler) 
     .failureHandler(ajaxAuthenticationFailureHandler) 
     .usernameParameter("j_username") 
     .passwordParameter("j_password") 
     .permitAll() 
    .and() 
     .logout() 
     .logoutUrl("/api/logout") 
     .logoutSuccessHandler(ajaxLogoutSuccessHandler) 
     .deleteCookies("JSESSIONID") 
     .permitAll() 
    .and() 
     .headers() 
     .frameOptions() 
     .disable() 
    .and() 
     .authorizeRequests() 
     .antMatchers("/api/register").permitAll() 
     .antMatchers("/api/activate").permitAll() 
     .antMatchers("/api/authenticate").permitAll() 
     .antMatchers("/api/account/reset_password/init").permitAll() 
     .antMatchers("/api/account/reset_password/finish").permitAll() 
     .antMatchers("/api/logs/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/api/**").authenticated() 
     .antMatchers("/metrics/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/health/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/trace/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/dump/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/shutdown/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/beans/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/configprops/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/info/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/autoconfig/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/env/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/trace/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/api-docs/**").hasAuthority(AuthoritiesConstants.ADMIN) 
     .antMatchers("/protected/**").authenticated() 
    .and() 
     .authorizeRequests() 
     .antMatchers("/basicAuthApi/**") 
     .hasAuthority(AuthoritiesConstants.USER).and().httpBasic(); 

Я только добавил:

.and() 
     .csrf() 
     .ignoringAntMatchers("/basicAuthApi/**") 

и:

.and() 
     .authorizeRequests() 
     .antMatchers("/basicAuthApi/**") 
     .hasAuthority(AuthoritiesConstants.USER).and().httpBasic() 

Вы также можете создать новый орган, который может получить доступ только к этим веб-службам.