如何使用 Spring 安全性和 Restful Web 服务验证数据库中的凭据?

Posted

技术标签:

【中文标题】如何使用 Spring 安全性和 Restful Web 服务验证数据库中的凭据?【英文标题】:How can I validate the credentials in my database using Spring security and Restful web services? 【发布时间】:2017-05-20 06:04:21 【问题描述】:

我对 Spring 安全性非常陌生。我想创建一个带有基本身份验证和 RestFul Webservices 的 Spring 安全应用程序。我也在使用 Spring Data JPA。

我已经通过互联网浏览了一些示例。他们中的大多数在 spring 应用程序本身中都有一个登录 UI 表单。它也没有验证来自数据库的凭据。

但我的情况:我有一个单独的 UI 应用程序,从我的客户端应用程序我将发送一个登录 url (Restful api) 调用。我想使用来自我的 Spring 应用程序的请求,并且应该从数据库中验证凭据。

【问题讨论】:

你必须实现org.springframework.security.core.userdetails.UserDetailsService。看到这个github.com/pallavJha/EventApp/blob/master/event-webapp/src/main/… 王子,您在下面提供的帮助下进展如何? 【参考方案1】:

方法一

配置Spring Security 以根据数据库凭据进行身份验证的简单方法,您可以使用jdbcAuthentication() 方法。所需的最低配置 如下:

@Autowired
DataSource dataSource;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception 
    
      auth
       .jdbcAuthentication()
       .dataSource(dataSource);


您唯一必须配置的是 DataSource 以便它能够访问您的数据库。

这个最小配置将适用于您的一些假设 数据库架构。它期望某些表存在,用户数据将被保存。

更具体地说,Spring Security 内部的以下 sn-p 代码显示了

查找用户详细信息时将执行的 SQL 查询:

JdbcDaoImpl

public static final String DEF_USERS_BY_USERNAME_QUERY = "select username,password,enabled "
            + "from users " + "where username = ?";


public static final String DEF_AUTHORITIES_BY_USERNAME_QUERY = "select username,authority "
            + "from authorities " + "where username = ?";


public static final String DEF_GROUP_AUTHORITIES_BY_USERNAME_QUERY = "select g.id, g.group_name, ga.authority "
            + "from groups g, group_members gm, group_authorities ga "
            + "where gm.username = ? " + "and g.id = ga.group_id "
            + "and g.id = gm.group_id";

第一个查询检索用户的用户名、密码以及他们是否是 启用。此信息用于对用户进行身份验证。下一个查询查找 用户授予的权限用于授权目的,最终查询查找授予用户作为组成员的权限。

如果您不想坚持使用 Spring Security 强制执行的默认数据库结构,您可以这样做

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception 
    auth.jdbcAuthentication()
        .dataSource(dataSource)
        .usersByUsernameQuery("select username, password, true from <tbl_name> where username=?")
        .authoritiesByUsernameQuery("select username, 'ROLE_ADMIN' from <tbl_name> where username=?");

在这种情况下,您只是覆盖了身份验证和基本授权 查询。但是您也可以通过调用 groupAuthoritiesByUsername() 来覆盖组权限查询 使用自定义查询。

在覆盖默认架构时,您需要遵循查询的基本约定。这里要注意的一点是,这些查询只接受用户名作为参数。权限查询选择零个或多个包含用户名和授予权限的行。组权限查询选择零个或多个行,每行都带有组 ID、组名称和权限。

方法二实现UserDetailsS​​ervice

您需要实现UserDetailsService 接口。

您需要做的就是实现loadUserByUsername() 方法以根据用户的用户名查找用户。 loadUserByUsername() 然后返回代表给定用户的UserDetails 对象。

基本实现

public class SomeUserService implements UserDetailsService 

    private final SomeRepository someRepository;

    public SomeUserService(SomeRepository someRepository) 
        this.someRepository = someRepository;
    

    @Override
    public UserDetails loadUserByUsername(String username)
        throws UsernameNotFoundException 
        UserClass userObject = someRepository.findByUsername(username);
        
        if (userObject != null) 
            List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
            authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
            
            return new User(
                userObject.getUsername(),
                userObject.getPassword(),
                authorities
            );
        
        
        throw new UsernameNotFoundException(
            "User '" + username + "' not found.");
    

然后

@Autowired
    SomeRepository someRepository;

    @Override
    protected void configure(AuthenticationManagerBuilder auth)
        throws Exception 
        auth
            .userDetailsService(new SomeUserService(someRepository));
    

【讨论】:

【参考方案2】:

查看这篇文章,它描述了如何使用 REST 端点执行登录: http://www.baeldung.com/securing-a-restful-web-service-with-spring-security

您可以通过将身份验证提供程序修改为以下内容来使用数据库中的凭据:

<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>

或者,正如 Obi Wan - PallavJha 所写,实现 UserDetailService 并将其插入使用

<authentication-provider user-service-ref="YourUserDetailService" />

【讨论】:

以上是关于如何使用 Spring 安全性和 Restful Web 服务验证数据库中的凭据?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Restful Web 服务的安全性

jax-rs RESTful 服务的 spring 安全配置

如何使用 Spring Security 做一个 RESTful 登录 API?

使用Spring Security和OAuth2实现RESTful服务安全认证

使用 Spring Security 在 Web 应用程序和 RESTful 服务之间共享安全上下文

Spring MVC、RESTful 服务和 Apache Shiro 策略