Chvalov
@Chvalov

Как быть с authorizeRequests после переноса с XML в Java Аннотации?

Переношу конфигы с XML в JavaConfig (SpringBoot)
<http auto-config="true">
        <intercept-url pattern="/" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')"/>
        <intercept-url pattern="/welcome" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')"/>
        <intercept-url pattern="/admin" access="hasRole('ROLE_ADMIN')"/>

        <form-login login-page="/login" default-target-url="/welcome" authentication-failure-url="/login?error"
                    username-parameter="username" password-parameter="password"/>

        <logout logout-success-url="/login?logout"/>
    </http>

    <authentication-manager alias="authenticationManager">
        <authentication-provider user-service-ref="userDetailsServiceImpl">
            <password-encoder ref="encoder"></password-encoder>
        </authentication-provider>
    </authentication-manager>

    <beans:bean id="userDetailsServiceImpl"
                class="net.proselyte.springsecurityapp.service.UserDetailsServiceImpl"></beans:bean>

    <beans:bean id="encoder"
                class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
        <beans:constructor-arg name="strength" value="11"/>
    </beans:bean>


Сделал так-же:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.
                authorizeRequests()
                .antMatchers("/", "/login").permitAll()
                .antMatchers("welcome").hasAnyRole("ROLE_USER", "ROLE_ADMIN")
                .antMatchers("/admin/**").hasRole("ROLE_ADMIN")
                    .anyRequest().authenticated()   //TODO Розобраться что это-такое
                .and()
                .formLogin()
                .loginPage("/login").failureUrl("/login?error")
                .defaultSuccessUrl("/welcome")
                .usernameParameter("username")
                .passwordParameter("password")
                .and().logout()
                .logoutSuccessUrl("/login?logout");
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth)
            throws Exception {
        auth.userDetailsService(userDetailsService()).passwordEncoder(
                passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        PasswordEncoder encoder = new BCryptPasswordEncoder();
        return encoder;
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return new UserDetailsServiceImpl();
    }
}


Получаю ошибку:
2017-11-14 22:40:09.713 ERROR 3972 --- [  restartedMain] o.s.boot.SpringApplication               : Application startup failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.IllegalArgumentException: role should not start with 'ROLE_' since it is automatically inserted. Got 'ROLE_ADMIN'
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]

........

	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-1.5.7.RELEASE.jar:1.5.7.RELEASE]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.IllegalArgumentException: role should not start with 'ROLE_' since it is automatically inserted. Got 'ROLE_ADMIN'
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]
	... 25 common frames omitted
Caused by: java.lang.IllegalArgumentException: role should not start with 'ROLE_' since it is automatically inserted. Got 'ROLE_ADMIN'
	at org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer.hasRole(ExpressionUrlAuthorizationConfigurer.java:242) ~[spring-security-config-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer.access$400(ExpressionUrlAuthorizationConfigurer.java:80) ~[spring-security-config-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer$AuthorizedUrl.hasRole(ExpressionUrlAuthorizationConfigurer.java:324) ~[spring-security-config-4.2.3.RELEASE.jar:4.2.3.RELEASE]
	at com.myprj.website.configuration.SecurityConfiguration.configure(SecurityConfiguration.java:26) ~[classes/:na]


Если заменить на hasRole на hasAuthority ошибки нету, но не понимаю какая между ними разница и будет ли работать авторизация должным образом

За основу был взят вот этот проект: SpringSecurityApp
  • Вопрос задан
  • 873 просмотра
Пригласить эксперта
Ответы на вопрос 1
В самом сообщении об ошибке есть рекомендация как это исправить:
role should not start with 'ROLE_' since it is automatically inserted. Got 'ROLE_ADMIN'


Если посмотреть исходники SpringSecurity там следующая картина:
private static String hasAnyRole(String... authorities) {
        String anyAuthorities = StringUtils.arrayToDelimitedString(authorities, "','ROLE_");
        return "hasAnyRole('ROLE_" + anyAuthorities + "')";
    }

    private static String hasRole(String role) {
        Assert.notNull(role, "role cannot be null");
        if (role.startsWith("ROLE_")) {
            throw new IllegalArgumentException("role should not start with 'ROLE_' since it is automatically inserted. Got '" + role + "'");
        }
        return "hasRole('ROLE_" + role + "')";
    }


Соотвествено надо переписать JavaConfig следующим образом

http.
                authorizeRequests()
                .antMatchers("/", "/login").permitAll()
                .antMatchers("welcome").hasAnyRole("USER", "ADMIN")
                .antMatchers("/admin/**").hasRole("ADMIN")
                    .anyRequest().authenticated()   //TODO Розобраться что это-такое
                .and()
                .formLogin()
                .loginPage("/login").failureUrl("/login?error")
                .defaultSuccessUrl("/welcome")
                .usernameParameter("username")
                .passwordParameter("password")
                .and().logout()
                .logoutSuccessUrl("/login?logout");
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы