【问题标题】:SpringSecurity gives error 401 Bad CredentialsSpringSecurity 给出错误 401 Bad Credentials
【发布时间】:2019-07-18 18:18:29
【问题描述】:

我是 Spring Security 的新手,正在创建一个简单的应用程序来检查身份验证和授权。我在内存数据库中使用。即使我提供了正确的登录凭据,我也会收到错误 401 “Bad Credentials”错误。 我还在一些休息端点使用了 permitAll() 函数,但我也在这些端点上得到了登录提示。我尝试清除浏览器历史记录和缓存也没有成功。请帮忙。我正在附加代码。

SecurityConfig.java

    package com.example.demo;

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
    //Authentication using In Memory Database
    public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder)throws Exception{
        authenticationManagerBuilder.inMemoryAuthentication()
        .withUser("user").password("{noop}pass123").authorities("ROLE_USER")
        .and()
        .withUser("admin").password("{noop}pass123").authorities("ROLE_USER","ROLE_ADMIN");        
    }

    //Authorization
    @Override //Overriding configure to use HttpSecurity for web based HTTP requests
    public void configure(HttpSecurity httpSecurity)throws Exception{
        httpSecurity.
        authorizeRequests()
        .antMatchers("/protectedbyuserrole*").hasRole("USER")
        .antMatchers("/protectedbyadminrole*").hasRole("ADMIN")
        .antMatchers("/","/notprotected").permitAll()
        .anyRequest().authenticated()
        .and()
        .httpBasic();    
    }
}

SpringSecurityApplication.Java

    package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;

@SpringBootApplication
@ComponentScan({"com.example.demo","controller"})
@Import({SecurityConfig.class})
public class SpringSecurityApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringSecurityApplication.class, args);
    }
}

TestSecurityController.Java

    package com.example.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestSecurityController {
    @RequestMapping("/")
    public String Hello() {
        return "Hello World!! ";
    }

    @RequestMapping("/notprotected")
    public String HelloAgain() {
        return "Hello from a non protected user!! ";
    }

    @RequestMapping("/protectedbyuserrole")
    public String HelloUser() {
        return "Hello User Role!! ";
    }

    @RequestMapping("/protectedbyadminrole")
    public String HelloAdmin() {
        return "Hello Admin Role!! ";
    }
}

POM.xml

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.19.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>SpringSecurity-1</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>SpringSecurity-1</name>
    <description>SpringSecurity for Authentication and Authorization</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

查询

还告诉我如何使用可以在邮递员中使用的简单密码。我应该使用 {noop} 还是只写密码,如 .password("pass123")。

我应该在 .antmatchers() 中使用单个 * 还是 ** 星号

我也使用 Postman 和 Firefox 进行了尝试。到处都是同样的错误。 POSTMAN SCREENSHOT

【问题讨论】:

  • 你能发布你的 pom/build 文件吗?
  • 请检查。我已经更新了我的 POM 文件。
  • 除已回答的内容外,在您的 Postman 屏幕截图中,您使用了用户名 user123 和密码 pass,但在您的安全配置中,您有用户名 user 和密码 @987654330 @,所以那些也不匹配。
  • 用户名和密码不同,因为我更改了要检查的凭据。
  • 请不要破坏您的帖子。您可以删除一些与问题无关的代码。但请以不会使下面提供的答案无效的方式对其进行编辑。根据 SE 政策,任何破坏行为都将被撤销。如果您想取消此帖子与您的帐户的关联,请参阅What is the proper route for a disassociation request?

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


【解决方案1】:

在 RequestMapping 中指定特定方法(GET、POST 等)是您可能需要遵循的好习惯。

我分享了一个我过去做过的基本示例。 您可以在浏览器中尝试使用用户名作为 myusername 和密码作为 mypassword 如果您仍然遇到问题,请通过您的邮递员屏幕截图告诉我

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

            auth.inMemoryAuthentication()
                .withUser("myusername")
                .password("mypassword")
                .roles("USER");
        }

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

             http
             .csrf().disable()
             .authorizeRequests().antMatchers("/login","/home","/failure").permitAll()
             .antMatchers(HttpMethod.POST,"/admin/**").hasRole("ADMIN") 
             .antMatchers(HttpMethod.PUT,"/admin/**").hasRole("ADMIN")
             .antMatchers(HttpMethod.GET,"/admin/**").hasRole("ADMIN")
             .antMatchers(HttpMethod.GET,"/user/**").hasAnyRole("ADMIN","USER")
             .antMatchers(HttpMethod.POST,"/user/**").hasAnyRole("ADMIN","USER")
             .anyRequest().authenticated();

    }

编辑

映射使用以下规则匹配 URL:

  • ?匹配一个字符

  • 匹配零个或多个字符

  • ** 匹配路径中的零个或多个目录

{spring:[a-z]+} 匹配正则表达式 [a-z]+ 作为名为“spring”的路径变量

Refer Path Matcher Here

 @RequestMapping(value="/protectedbyuser",method=RequestMethod.GET)
        public String Hello() {
            return "Hello Protected By User!! ";
        }

【讨论】:

  • 在 HttpSecurity 代码块(第二个)中,我应该在 .antMatchers(HttpMethod.GET,"/user/**").hasAnyRole("ADMIN"," USER") 和 .antMatchers(HttpMethod.GET,"/protectedbyuser/**").hasAnyRole("ADMIN","USER") 按照我上面的代码逻辑?我试图改变这种方式,但现在我得到错误 403 访问被拒绝而不是错误 401 错误凭据。请根据我的程序帮助我应该做出哪些改变。
  • 是的,您可以根据自己的要求编写任何请求名称,但好的做法是使用 user.所以现在凭证是有效的,你会得到 403 Forbidden。在邮递员中成功登录后,在浏览器中使用相同的凭据而不是邮递员登录一件事请​​分享您的邮递员截图
  • 那么我想我需要相应地更改我的 REST 端点的名称,因为目前您可以从我的代码中看到,我已将 protectedbyuser 添加为端点,而不仅仅是用户。我只是将它用于测试目的。我无法在此处添加屏幕截图,因此我在主要问题上添加了邮递员的屏幕截图。请检查。
  • 查看编辑并使用您的用户管理员凭据登录以获得所有访问权限,并使用您的用户凭据登录以获得有限访问权限
  • 在您编写的不同 antmatcher 查询中,应该使用哪种 HTTP 方法进行登录?获取还是发布?我很困惑,因为在这里我们没有向数据库发布任何内容,所以没有 POST 的意义。我错了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-10
  • 2023-01-05
  • 2020-05-13
  • 2012-04-25
  • 2013-07-20
相关资源
最近更新 更多