【问题标题】:Spring Security users-by-username-query with id_userSpring Security users-by-username-query with id_user
【发布时间】:2018-03-29 22:28:28
【问题描述】:

我想使用 Spring Security,但我以前从未使用过它。我想从我的表中检索用户和角色(用户、角色和 user_roles)。我已经调查了 users-by-username-query 。在所有示例中都与以下示例相同。

<authentication-manager>
  <authentication-provider>
    <jdbc-user-service data-source-ref="dataSource"
      users-by-username-query=
        "select username,password, enabled from users where username=?"
      authorities-by-username-query=
        "select username, role from user_roles where username =?  " />
  </authentication-provider>
</authentication-manager>

但我想使用 id_userid_role 而不是 usernamerole。可能吗 ?我必须更改登录页面字段名称吗? 在此先感谢

【问题讨论】:

  • 这里有一个很好的讨论stackoverflow.com/questions/9069019/…
  • 为什么你不检索你的字段 id_userid_role 而只是在同一个查询中为它们应用别名?这可能是实现这一目标的最简单方法。我已经做过几次了:users-by-username-query=" select user.user_login as username, user.user_pwd as password, user.user_enabled as enabled from user where user.user_login=?"
  • 好的,如果可以像你说的那样使用我会试试的。谢谢你的回复。
  • 但是我的 user_role 表没有代表角色名称的列
  • 我如何通过用户名查询声明我的权限?

标签: spring spring-mvc authentication spring-boot spring-security


【解决方案1】:

对于字符串启动 2 是这样工作的

package com.gkatzioura.spring.security.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import javax.sql.DataSource;


@Configuration
@EnableWebSecurity
public class PasswordEncodedSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private DataSource dataSource;

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

        auth.jdbcAuthentication().dataSource(dataSource)
                //.passwordEncoder(new BCryptPasswordEncoder())
                .passwordEncoder(passwordEncoder())
                .usersByUsernameQuery("select username,password,enabled from users where username =?")
                .authoritiesByUsernameQuery(" select u.username, r.name from users u join user_role ur on u.id = ur.user_id " +
                        " join role r on ur.role_id = r.id where u.username =?");
    }

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

        http.authorizeRequests()
                .antMatchers("/public").permitAll()
                .anyRequest().authenticated()
                .and().formLogin().permitAll()
                .and().logout() .permitAll();
    }
    
    
    @Bean
    public PasswordEncoder passwordEncoder(){
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        return passwordEncoder;
    }
    

}

【讨论】:

  • 是什么阻止了自定义查询中的 SQL 注入?
【解决方案2】:

这是一种常见的情况。

首先,正如我在 cmets 中建议的那样,使用别名来重命名代表用户名、密码以及用户是否启用的字段。就像这样:

users-by-username-query=
  "select user.user_login as username, user.user_pwd as password, user.user_enabled as enabled 
  from user where user.user_login=?"

然后,通常也将authorities 放在与user 表相关的不同表中。这是一种常见的情况:

用户与n-to-n 关系中的角色相关。

在这种情况下,authorities-by-username-query 应该是这样的

 authorities-by-username-query=
        "SELECT users.name as username, roles.role as role 
        FROM users 
        INNER JOIN user_role ON users.id_user = user_role.id_user 
        INNER JOIN roles ON user_role.id_role = roles.id_role
        WHERE users.name = ?  "

作为测试,对于包含此数据的一组表:

用户:

角色:

用户角色

对于收到的用户名jlumietu,结果应该是这样的:

最后,我遇到了一些扩展 org.springframework.security.authentication.dao.DaoAuthenticationProvider 的案例,但我认为这是进行此类处理的最简单方法

【讨论】:

  • 我已经尝试过您的解决方案,但它仍然不适合我。我只收到错误 401 未经授权的请求。基本上整个认证都没有通过。
  • @ChandaraChea 这是一个经过良好测试的解决方案,我已经在很多应用程序中运行过。如果如您所说的“整个身份验证没有通过”,我认为您应该检查过滤器映射。如果你愿意,你可以写和回答并在这里发布一个链接,我会尽快检查它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-22
  • 1970-01-01
  • 1970-01-01
  • 2021-08-27
  • 2019-03-15
  • 1970-01-01
  • 2012-02-22
相关资源
最近更新 更多