базовая HTTP-аутентификация Spring Boot с несколькими ролями выдает 403 запрещенную ошибку

Я пытаюсь настроить базовую HTTP-аутентификацию Spring Boot-Embedded Tomcat с несколькими ролями, причем большинство URL-адресов похожи, но некоторые из них специфичны для каждой роли. Здесь для первой роли всплывает базовая HTTP-аутентификация и работает нормально. С кодом ниже,

    @Configuration
    @EnableWebMvcSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)

public class TestSecurityAdapter extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests().antMatchers(null, getAppAdminRolePaths()).authenticated()
                .anyRequest().hasAnyRole("APPADMIN")
                .and()
                .httpBasic();

        http.csrf().disable()
                .authorizeRequests().antMatchers(null, getAppUserRolePaths()).authenticated()
                .anyRequest().hasAnyRole("APPUSER")
                .and()
                .httpBasic();

        http.authorizeRequests().antMatchers(null, new String[]{"/app/appOwnerView.html"}).authenticated()
                .anyRequest().hasAnyRole("APPOWNER")
                .and()
                .httpBasic();
    }

    @Override
    @Autowired
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("appadminname").password("appadminpwd").roles("APPADMIN").and()
        .withUser("appusername").password("appuserpwd").roles("APPUSER").and()
        .withUser("appownername").password("appoownerpwd").roles("APPOWNER");
    }

    private static String[] getAppAdminRolePaths(){
        return new String[]{"/appweb/*",
                "/app/checkService.html",               
                "/app/index.html",                
                "/app/testData.html",    
                "/app/adminView.html", 
                "/app/demo.html"};
    }

    private static String[] getAppUserRolePaths(){
        return new String[]{"/appweb/*",
                "/app/checkService.html",               
                "/app/index.html",                
                "/app/testData.html",    
                "/app/userView.html", 
                "/app/demo.html"};
    }
}

Для всплывающего окна имени пользователя/пароля HTTP в браузере с URL-адресом http://localhost:8080/app/index.html скажем, с appadminname/appadminpwd все работает нормально. Но для того же URL-адреса, если я ввожу appusername/appuserpwd, он выдает HTTP 403 Forbidden access error. Вот почему вторая настроенная роль APPUSER выдает эту ошибку, я не уверен. Пожалуйста, дайте знать, если какой-то способ решить эту проблему.

Спасибо


person Chakri    schedule 19.06.2015    source источник


Ответы (1)


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

Во-первых, я не уверен, почему ваши вызовы antMatchers() предоставляют null в качестве первого аргумента; antMatchers() ожидает список строк, определяющих URL-адреса, на которые распространяется это правило, поэтому я не уверен, что в этом случае ожидается соответствие null.

Во-вторых, anyRequest() означает, что это правило будет применяться к любому запросу, сделанному к приложению, независимо от используемого URL-адреса, и Spring будет применять правила безопасности в том порядке, в котором они определены. Обычно вы сначала определяете URL-адреса и связанные с ними роли, а затем по умолчанию используете правило для любого другого запроса, который должен быть аутентифицирован (но не обязательно требует каких-либо конкретных ролей) с чем-то вроде anyRequest().authenticated()

Ваше первое правило гласит, что любой запрос к приложению должен быть сделан пользователями с ролью APPADMIN, которая запрещает вам доступ, когда вы пытаетесь войти в систему как appusername, поэтому второе правило, разрешающее APPUSER, не даже обработанный.

В-третьих, вы делаете несколько вызовов http.authorizeRequests(), хотя на самом деле вам, вероятно, следует связывать их вместе, например:

http.csrf().disable().authorizeRequests()
    .antMatchers( getAppAdminRolePaths() ).hasRole("APPADMIN")
    .antMatchers( getAppUserRolePaths() ).hasRole("APPUSER")
    .anyRequest().authenticated();


Наконец, когда у вас есть только одна роль для проверки, вы можете использовать hasRole() вместо hasAnyRole().

Вам также не нужно указывать аутентификацию() и hasRole() в одном и том же правиле, потому что hasRole() подразумевает, что пользователь уже аутентифицирован.

Дополнительные пояснения и примеры можно найти в документации Spring: http://docs.spring.io/spring-security/site/docs/4.0.3.RELEASE/reference/htmlsingle/#authorize-requests

person Sam Williams    schedule 08.12.2015