jdbcAuthentication() 而不是 inMemoryAuthentication() 不授予访问权限 - Spring Security 和 Spring Data JPA [英] jdbcAuthentication() instead of inMemoryAuthentication() doesn't give access - Spring Security and Spring Data JPA

查看:49
本文介绍了jdbcAuthentication() 而不是 inMemoryAuthentication() 不授予访问权限 - Spring Security 和 Spring Data JPA的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是使用 spring mvc、gradle、spring security、spring data jpa 创建简单的应用程序.现在我想测试 spring security 是如何工作的,但我有一个问题.首先我给你看一些代码,然后我会提到我的问题.

I'm just creating simple app using spring mvc, gradle, spring security, spring data jpa. Now I would like to test how spring security works, but I have a problem. First I show you little code then I will mention about my problem.

结构:

Person.java

package com.test.business;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "person")
public class Person {

  @Id
  @Column(name = "id")
  private int id;
  @Column(name = "name")
  private String name;
  @Column(name = "password")
  private String password;
  @Column(name = "role")
  private String role;

  public Person(){
  }

  public Person(int id, String name, String password, String role) {
    this.id = id;
    this.name = name;
    this.password = password;
    this.role = role;
  }
  //setters and getters
}

PersonController.java

package com.test.controller;

import com.test.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class PersonController {

  @Autowired
  private PersonService personService;

  @GetMapping(value="/")
  @ResponseBody
  public String printWelcome() {
    return "home";
  }

  @GetMapping(value="/admin")
  @ResponseBody
  public String admin() {
    return "admin";
  }

  @GetMapping(value="/user")
  @ResponseBody
  public String user() {
    return "user";
  }
}

MyWebInitializer.java

package com.test.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class MyWebInitializer extends
    AbstractAnnotationConfigDispatcherServletInitializer {

  @Override
  protected Class<?>[] getRootConfigClasses() {
    return new Class[] { RootConfig.class, SecurityConfig.class };
  }

  @Override
  protected Class<?>[] getServletConfigClasses() {
    return new Class[] { WebConfig.class };
  }

  @Override
  protected String[] getServletMappings() {
    return new String[] { "/" };
  }

}

SecurityWebInitializer.java

package com.test.config;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SecurityWebInitializer
    extends AbstractSecurityWebApplicationInitializer {

}

RootConfig.java

package com.test.config;

import java.util.Properties;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableJpaRepositories( basePackages = {"com.test.repository"})
@PropertySource(value = { "classpath:application.properties" })
@EnableTransactionManagement
@Import({ SecurityConfig.class })
@ComponentScan(basePackages = {"com.test.service", "com.test.repository", "com.test.controller", "com.test.business"})
public class RootConfig {

  @Autowired
  private Environment environment;

  @Autowired
  private DataSource dataSource;

  @Bean
  public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
    dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
    dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
    dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));

    return dataSource;
  }

  @Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setDatabase(Database.POSTGRESQL);
    vendorAdapter.setGenerateDdl(true);
    vendorAdapter.setShowSql(true);

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setJpaVendorAdapter(vendorAdapter);
    factory.setPackagesToScan("com.test.business");
    factory.setDataSource(dataSource());
    factory.setJpaProperties(jpaProperties());

    return factory;
  }

  private Properties jpaProperties() {
    Properties properties = new Properties();
    properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
    properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
    properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
    return properties;
  }
  @Bean
  public PlatformTransactionManager transactionManager() {

    JpaTransactionManager txManager = new JpaTransactionManager();
    txManager.setEntityManagerFactory(entityManagerFactory().getObject());
    return txManager;
  }
}

WebConfig.java

package com.test.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@EnableWebMvc
@Configuration
@ComponentScan({ "com.test.controller" })
public class WebConfig implements WebMvcConfigurer {

  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/resources/**")
        .addResourceLocations("/resources/");
  }

  @Override
  public void configureViewResolvers(ViewResolverRegistry registry) {
    registry.jsp().prefix("/WEB-INF/views/").suffix(".jsp");
  }

}

SecurityConfig.java

package com.test.config;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Autowired
  private DataSource dataSource;

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {

    auth.jdbcAuthentication().dataSource(dataSource)
        .usersByUsernameQuery("select name, password"
            + " from person where name=?")
        .authoritiesByUsernameQuery("select name, role"
            + "from person where name=?");
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests().antMatchers("/admin").hasRole("ADMIN")
        .and()
        .httpBasic(); // Authenticate users with HTTP basic authentication
  }
}

在数据库中记录为 JSON:

{
    "id": 1,
    "name": "test1",
    "password": "test1",
    "role": "ADMIN"
}

问题是什么?查看 SecurityConfig.java.有 jdbcAuthentication().当我尝试访问/admin 浏览器会要求我输入用户名和密码.不幸的是,当我这样做时什么也没发生,浏览器会一遍又一遍地询问.

And what's the problem? Look at SecurityConfig.java. There is jdbcAuthentication(). When I try access to /admin browser will ask me to put username and password. Unfortunately, when I do that nothing happend and browser will ask again, and again.

我修改了一些代码.在 SecurityConfig.java 而不是 jdbcAuthentication() 我使用了 inMemoryAuthentication() 所以它看起来像:

I changed a little me code. In SecurityConfig.java instead of jdbcAuthentication() I used inMemoryAuthentication() so it looked like:

SecurityConfig.java

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Autowired
  private DataSource dataSource;

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {

    auth.inMemoryAuthentication().withUser("user").password("password").roles("ADMIN");
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests().antMatchers("/admin").hasRole("ADMIN")
        .and()
        .httpBasic(); // Authenticate users with HTTP basic authentication
  }
}

现在我尝试访问/admin.浏览器要求我输入用户名和密码,当我这样做时,我将获得对/admin 的访问权限.为什么?为什么我无法使用 jdbcAuthentication() 获得访问权限?你能给我一些建议吗?

Now I try access to /admin. Browser asks me to put username and password and when I do that I will get a access to /admin. Why is that? Why cannot I get a access using jdbcAuthentication()? May you give me some advices?

推荐答案

我猜错在你的查询中

auth.jdbcAuthentication().dataSource(dataSource)
    .usersByUsernameQuery("select name, password"
        + " from person where name=?")
    .authoritiesByUsernameQuery("select name, role"
        + "from person where name=?");

jdbcAuthentication 需要

jdbcAuthentication expects

  • 对于users-by-username-query:usernamepasswordenabled
  • 对于authorities-by-username-query usernamerole
  • for users-by-username-query : username, password and enabled
  • for authorities-by-username-query username and role

所以对你来说这应该有效:

so for you this should work:

auth.jdbcAuthentication().dataSource(dataSource)
    .usersByUsernameQuery("select name as username, password, true"
        + " from person where name=?")
    .authoritiesByUsernameQuery("select name as username, role"
        + " from person where name=?");

这篇关于jdbcAuthentication() 而不是 inMemoryAuthentication() 不授予访问权限 - Spring Security 和 Spring Data JPA的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆