Несанкционированные вызовы после настройки Spring security

#java #mysql #spring #spring-security

#java #mysql #spring #spring-безопасность

Вопрос:

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

Итак, мои Entity классы выглядят так

 class User {
    @Id
    @GeneratedValue
    @Column(name = "user_id")
    private Integer id;

    @Column
    private String username;

    @Column
    private String password;

    @ManyToMany
    @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> roles;
}

class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "role_id")
    private Integer id;

    @Column(name = "role")
    private String role;
}
  

И моя конфигурация безопасности

 @Configuration
class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Value("${spring.queries.users-query}")
    private String usersQuery;

    @Value("${spring.queries.roles-query}")
    private String rolesQuery;

    private DataSource dataSource;

    public SecurityConfiguration(DataSource dataSource) {
        this.dataSource = dataSource;
    }

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

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.jdbcAuthentication()
            .usersByUsernameQuery(usersQuery)
            .authoritiesByUsernameQuery(rolesQuery)
            .dataSource(dataSource)
            .passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic()
            .and()
            .authorizeRequests()
            .antMatchers(HttpMethod.GET, "/task/**").hasRole("USER")
            .and()
            .csrf().disable()
            .formLogin().disable();
    }
}
  

И, наконец,, application.properties

 spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/teamplanner?useUnicode=trueamp;useJDBCCompliantTimezoneShift=trueamp;useLegacyDatetimeCode=falseamp;serverTimezone=Europe/Warsaw
spring.datasource.username=root
spring.datasource.password=root

spring.queries.users-query=select username, password from user where username=?
spring.queries.roles-query=select u.username, r.role from user u inner join user_role ur on(u.user_id=ur.user_id) inner join role r on(ur.role_id=r.role_id) where u.username=?
  

Теперь я пытаюсь вызвать / task / all с базовой авторизацией в postman, и я получаю

 {
    "timestamp": "2019-04-21T22:50:17.189 0000",
    "status": 401,
    "error": "Unauthorized",
    "message": "Unauthorized",
    "path": "/task/all"
}
  

Оба запроса, которые я сохранил в application.properties, возвращают записи, если я запускаю их непосредственно в базе данных

Ответ №1:

вы должны сообщить Spring security, что пользователь включен, см. Исходный код в JdbcDaoImpl

введите описание изображения здесь

поэтому вам следует изменить конфигурацию spring.queries.users-query

 spring.queries.users-query=select username, password, 1 from user where username=?
  

если вы все еще не можете понять это, измените значение имени роли с USER на ROLE_USER