与 mongodb 后端数据库的基于 Spring Security 的身份验证混淆

     2023-02-26     52

关键词:

【中文标题】与 mongodb 后端数据库的基于 Spring Security 的身份验证混淆【英文标题】:Confusion with Spring Security-based authentication with mongo backed db 【发布时间】:2016-12-12 18:21:39 【问题描述】:

我正在尝试将用户登录到一个网页,其中凭据存储在 mongodb 中。 我正在使用 spring boot,但不知道 spring 安全功能。

这就是我最终使用以下控制器代码的原因:

@RequestMapping("/auth")
String auth(@ModelAttribute("credential") Credential credential) throws AuthenticationFailedException 
    handler.authenticateUser(credential);
    log.debug("user: " + credential.getUsername() + " authenticated successfully via /auth");
    return "main";

处理程序:

@Autowired
private UserRepository repository;

public boolean authenticateUser(Credential credential) throws AuthenticationFailedException         
    User authenticatedUser = repository.findByCredentialUsername(credential.getUsername());

    if (authenticatedUser == null)
        throw new AuthenticationFailedException(
                "cant find any user with name: " + credential.getUsername());

    boolean matches = EncryptionUtils.matchEncryptedPassword(credential.getPassword(),
            authenticatedUser);

    if (!matches)
        throw new AuthenticationFailedException(
                "provided password is not matching password stored in database");

    return matches;

在意识到使用 spring-security 设置 servlet 过滤器等相对容易之后,我更改了我的代码,所以我最终得到了这个:

配置:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter 

  @Autowired
  UserAuthenticationService userAuthService;

  @Bean
  public DaoAuthenticationProvider daoAuthenticationProvider() 
    DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
    provider.setUserDetailsService(userAuthService);
    provider.setPasswordEncoder(new BCryptPasswordEncoder());
    return provider;
  

  @Override
  protected void configure(HttpSecurity http) throws Exception 
    http.userDetailsService(userAuthService).authorizeRequests()
            .antMatchers("/register", "/", "/css/**", "/images/**", "/js/**", "/login")
            .permitAll().anyRequest().authenticated().and().
            formLogin().loginPage("/").and().sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().csrf().disable();

  

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception 
    auth.authenticationProvider(daoAuthenticationProvider());
  

SecurityWebInit:

public class SecurityWebInit extends AbstractSecurityWebApplicationInitializer 
  public SecurityWebInit() 
    super(SecurityConfig.class);
  

用户认证服务:

@Component
public class UserAuthenticationService implements UserDetailsService 
  private static final Logger log = Logger.getLogger(UserAuthenticationService.class);
  @Autowired
  private UserRepository repository;

  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException 
        User user = repository.findByCredentialUsername(username);
        log.debug("called user auth service..");
        if (user == null)
            throw new UsernameNotFoundException("username :"+username+" not found.");
        else 
            AuthenticatedUser authUser = new AuthenticatedUser(user);
            return authUser;
        
  

AuthenticatedUser - 型号:

public class AuthenticatedUser implements UserDetails   
  private User user; // user is my own model, not of spring-framework
  private static final Logger log = Logger.getLogger(AuthenticatedUser.class);

  public AuthenticatedUser(User user) 
      this.user = user;
  
  .. //rest of interface impl. (any method returns true)

  //no roles or authorities modeled, yet
  @Override 
  public Collection<? extends GrantedAuthority> getAuthorities() 
      return null;
  

修改后的控制器:

@RequestMapping(method=RequestMethod.POST, value="/login")
String auth2(@RequestParam("username") String username, @RequestParam("password") String password) throws AuthenticationFailedException 
    Credential cred = new Credential();
    cred.setUsername(username);
    cred.setPassword(password);        
    handler.authenticateUser(cred);
    log.debug("user: " + cred.getUsername() + " authenticated successfully via /login");
    return "main";

模板:

<form method="post" action="/login" th:object="$credential">
    <div class="form-group">
     <input type="email" th:field="*username" class="form-control"
      id="username" placeholder="Username/Email" />
    </div>
    <div class="form-group">
     <input type="password" th:field="*password"
      class="form-control" id="password" placeholder="Password" />
    </div>
    <button type="submit" class="btn btn-default login-button">Submit</button>
</form>

所有提供的代码,从其他教程和示例中聚集在一起的更少。 当我通过基于表单的登录进行身份验证时,它确实有效。但是在我登录后,当我导航到localhost:8080/&lt;anyRestrictedUrl&gt; 时,它仍然会将我重定向到登录表单。 我还在UserAuthenticationService 中放置了一些log.debug(..),但我根本看不到它们中的任何一个.. 在大多数其他示例中,我什至看不到映射到 \login 的基本控制器方法,但我认为这是因为 spring 在幕后做了这 4 个我?!

请注意,我没有使用任何权限和/或角色,因为它还没有在 db 中建模。在使用 Spring Security 时,这是必须具备的吗,因为大多数示例都包括角色和权限。

编辑:(pom.xml 的相关部分):

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.3.RELEASE</version>
    <relativePath />
</parent>

 <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
 </dependency>
 <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-thymeleaf</artifactId>
 </dependency>
 <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-crypto</artifactId>
 </dependency>
 <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-core</artifactId>
 </dependency>
 <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-config</artifactId>
 </dependency>
 <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-web</artifactId>
 </dependency>
 <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-taglibs</artifactId>
 </dependency>

更新:(我在上面提到的代码上试过的东西):

1)设置其他会话策略:(不工作)

http.userDetailsService(userAuthService).authorizeRequests()
    .antMatchers("/register", "/", "/css/**", "/images/**", "/js/**", "/login")
    .permitAll().anyRequest().authenticated().and().
    formLogin().loginPage("/").and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS).and().csrf().disable();

2) 将 @Override 替换为 @Autowired 注释(从另一个 SO 帖子中获得 - 不起作用):

@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception 
    auth.authenticationProvider(daoAuthenticationProvider());

【问题讨论】:

您在哪里指定了您的受限 URL? 不是在configure(HttpSecurity http):...anyRequest().authenticated()完成的 【参考方案1】:

我可以解决这个.. 阅读this blog post 事实证明,这是需要的!在config(HttpSecurity http) 中指定usernameParameter(..), passwordParameter(..),这与它们在许多基本示例或教程中所做的不同。所以依赖默认值是我的遗憾。我必须附加:

formLogin().loginPage("/")
       .loginProcessingUrl("/login")
       .failureUrl("/")
       .defaultSuccessUrl("/main")
       .usernameParameter("username") //needed, if custom login page
       .passwordParameter("password") //needed, if custom login page

没有这些参数设置,UserDetailsService 实现不会被触发。

希望对大家有所帮助。

【讨论】:

【参考方案2】:

将您的 SessionCreationPolicy 更改为 IF_REQUIREDALWAYS。目前,它是“无状态的”,这意味着您的会话将永远不会为 SecurityContext 创建或获取。

【讨论】:

我试过了,但还是不行。还尝试从配置中完全删除sessionManagement(),但结果相同

java版本,java版本mongodb驱动,驱动与mongodb数据库,spring之间的兼容性

JavaDriverCompatibilityMongoDBCompatibility(驱动与数据库兼容)JavaDriverVersionMongoDB4.2MongoDB4.0MongoDB3.6MongoDB3.4MongoDB3.2MongoDB3.0MongoDB2.6Version4.0✓✓✓✓✓✓✓Version3.12✓✓✓✓✓✓✓Version3.11✓✓✓✓✓✓✓Version 查看详情

基于 Spring Cloud 微服务与 Zuul 的 Spring CORS 过滤器问题

...:23【问题描述】:Given:Angular前端应用通过网关微服务向后端微服务发送请求。后端在SpringCloud中。问题:如何正确配置CORS过滤器以摆脱以下错误:Acce 查看详情

基于spring boot的项目中的spring data mongodb配置

】基于springboot的项目中的springdatamongodb配置【英文标题】:springdatamongodbconfigurationinspringbootbasedproject【发布时间】:2014-12-2709:25:09【问题描述】:我正在使用springboot编写代码,它将csv作为输入并创建mongodb集合并将其插入到mongodb... 查看详情

spring-data-mongodb中的mongotemplate与mongorepository

...、SpringData概述 SpringData:Spring的一个子项目。用于简化数据库访问,支持NoSQL和关系数据存储。其主要目标是使数据库的访问变得方便快捷。●SpringData项目所支持NoSQL存储:MongoDB(文档数据库)Neo4j(图形数据库)Redis(键/值... 查看详情

MongoDB 地理定位与 Spring MVC 一起使用

】MongoDB地理定位与SpringMVC一起使用【英文标题】:MongoDBGeolocationusingwithSpringMVC【发布时间】:2015-03-2812:46:08【问题描述】:我尝试为我的应用程序实施GPS跟踪服务。我有一项服务可以将地理位置数据推送到mongodb中,效果很好。... 查看详情

从 mongoDb 中提取基于小时的数据

...查询名称“updateTime”)。数据每1分钟更新一次。要将此数据库数据与其他数据匹配,我只需要从每小时更新中提取数据。例如,我只需要来自以下更新查询的数据:"update 查看详情

使用 Spring Security + Spring 数据 + MongoDB 进行身份验证

...ng安全性与MongoDB一起使用(使用Spring数据)并从我自己的数据库中检索用户以实现Spring安全性。但是,我不能这样做,因为我的用户服务类型似乎不受支持。 查看详情

mongodb介绍与安装

...源的,基于分布式的,面向文档存储的非关系型数据库。是非关系型数据库当中功能最丰富、最像关系数据库的。   mongoDB由C++编写,其名字来源于"humongous"这个单词,其宗旨在于处理大量数据。   ... 查看详情

window下mongodb的配置与安装

前言MongoDB是一个基于分布式文件存储的数据库。由C++语言编写,支持Windows,Linux,OSX,Solaris等平台,默认端口为27017,是一个效率非常高的nosql数据库。我的测试环境:window10 64位我的安装路径:D:mongodb我学习mongodb的笔记本... 查看详情

前端与后端处理

...视图。这里的HTTP响应非常大,并且只会随着数据添加到数据库 查看详情

Spring -Data MongoDB问题与作为接口的字段

】Spring-DataMongoDB问题与作为接口的字段【英文标题】:Spring-DataMongoDBissuewithfieldwhichisaninterface【发布时间】:2013-07-2810:34:17【问题描述】:我正在为MongoDB使用Spring-Data:版本信息-org.mongodb.mongo-java-driver版本2.10.1,org.springframework.da... 查看详情

java示例代码_脚本-如何基于Spring MVC显示来自后端系统的错误消息

java示例代码_脚本-如何基于Spring MVC显示来自后端系统的错误消息 查看详情

mongodb常用命令与安全加固

一、介绍MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数... 查看详情

SPA 的 Cookie 与基于令牌的身份验证?

...5-10-2921:30:02【问题描述】:我正在使用AngularJS和Spring作为后端构建单页应用程序。为了使我的后端无状态,我最近研究了JWT(JSONWebTokens)。现在这是混乱-一个。我应该将响应头上的JWT发送到客户端,然后通过ngCookie将其保存到co... 查看详情

Spring-data MongoDB地理查询

...信,我正在寻找一种执行地理查询的方法,该查询将通过数据库中给定的地理点检索附近的配置文件,我对查询的要求是:1)距离限制2)返回配置文件数量的限制3)根据配置文件中的时间字段进行额外搜索4)从检索到的文档中包含/... 查看详情

mongodb数据库1,mongodb的基本概念与基本数据类型(代码片段)

目录一、文档二、集合1、集合2、集合的命名三、数据库四、基本数据类型1、JSON数据类型2、MongoDB常见的数据类型3、ObjectId五、创建、更新、删除文档1、$set修饰符入门2、递增操作和递减操作六、数组运算符1、添加元素2、如果... 查看详情

NoSQL(MongoDB)与Lucene(或Solr)作为您的数据库[关闭]

】NoSQL(MongoDB)与Lucene(或Solr)作为您的数据库[关闭]【英文标题】:NoSQL(MongoDB)vsLucene(orSolr)asyourdatabase[closed]【发布时间】:2011-03-1400:04:16【问题描述】:随着基于文档数据库的NoSQL运动不断发展,我最近关注了MongoDB。我注意... 查看详情

记一次后端性能测试与调试(代码片段)

...G应用服务器(uwsgi+falsk)、三台2核8G的数据服务器(Redis+MongoDB,3台保证可用)、一台2核2G的配置和部署服务器。但实际开发时为节省成本,暂时将MongoDB、redi 查看详情