为了账号安全,请及时绑定邮箱和手机立即绑定

Spring 返回 401 而不是 200 状态

Spring 返回 401 而不是 200 状态

BIG阳 2021-11-24 18:33:17
我编写了一个应用程序作为学习 Spring 的一部分,但是当我测试身份验证时,我收到 401 状态而不是 200。我一直在寻找错误的原因,在我看来,该行Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(email, password));返回null. 但是,我不知道如何解决这个问题。@Componentpublic class AuthenticationServiceUsernamePassword {    private static final Logger LOGGER = LoggerFactory.getLogger(AuthenticationServiceUsernamePassword.class);    @Autowired    @Qualifier("customAuthenticationManager")    private AuthenticationManager authenticationManager;    @Autowired    private TokenManager tokenManager;    public SignedJWT authenticate(final String email, final String password){        try {            Authentication authentication = authenticationManager                .authenticate(new UsernamePasswordAuthenticationToken(email, password));                    SecurityContextHolder.getContext()                .setAuthentication(authentication);            if (authentication.getPrincipal() != null) {                return tokenManager.createNewToken((PrincipalUser) authentication.getPrincipal());            }        } catch (AuthenticationException authException) {            LOGGER.debug("Authentication failed for user:\"" + email + ".\" Reason " + authException.getClass());        }        return null;    }}
查看完整描述

3 回答

?
一只甜甜圈

TA贡献1836条经验 获得超5个赞

好的。第一件事


Email并Password正确通过


问题在这里


public SignedJWT authenticate(final String email, final String password){

        try {

            System.out.println("test => "+email+" : "+password);

            Authentication authentication = authenticationManager

                    .authenticate(new UsernamePasswordAuthenticationToken(email, password));

            SecurityContextHolder.getContext().setAuthentication(authentication);


            if (authentication.getPrincipal() != null) {

                return tokenManager.createNewToken((PrincipalUser) authentication.getPrincipal());

            }

        } catch (AuthenticationException authException) {

            authException.printStackTrace();

            LOGGER.debug("Authentication failed for user:\"" + email + ".\" Reason " + authException.getClass());

        }

        System.out.println("return nulll");

        return null;

    }

如果你运行你的测试用例,它会抛出以下错误


org.springframework.security.authentication.BadCredentialsException: Bad credentials

    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks(DaoAuthenticationProvider.java:98)

    at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:166)

    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)

    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199)

    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:504)

    at com.github.springjwt.security.jwt.service.AuthenticationServiceUsernamePassword.authenticate(AuthenticationServiceUsernamePassword.java:30)

    at com.github.springjwt.web.api.controller.AuthController.authenticate(AuthController.java:31)

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    at sun.reflect.NativeMethodAccessorImp

这意味着你的测试用例的username和passworddidnt匹配UserRepository类用户详细


在您的UserRepository课程中,您需要设置正确的散列密码及其已设置为 null 的盐值。


当您authenticate.authenticate 在内部调用它时,会获取密码和哈希并将其与传递的值进行匹配。


如果值不匹配,则会引发错误凭据错误


PS:我在本地运行你的代码后得出这个结论


查看完整回答
反对 回复 2021-11-24
?
喵喵时光机

TA贡献1846条经验 获得超7个赞

您的代码大部分是正确的,它在您的控制器定义中出错:

public ResponseEntity<String> authenticate(String email, String password, HttpServletRequest request,
                                           HttpServletResponse response){

默认情况下,Spring 不知道如何检索电子邮件和密码变量。您需要使用注释对这些进行@RequestBody注释,例如:

public ResponseEntity<String> authenticate(@RequestBody String email, @RequestBody String password, HttpServletRequest request,
                                           HttpServletResponse response){

但是,如果您的整个控制器将用作 API,您还可以使用@RestController它来注释您的控制器,它告诉 spring 使用@RequestBodyfor each 参数,并且每个方法都应该被注释,@ResponseBody这将告诉 spring 返回值应该转换为 JSON(这是方便的API)。


查看完整回答
反对 回复 2021-11-24
?
梦里花落0921

TA贡献1772条经验 获得超5个赞

您已向单元测试用例添加了参数。不是有效载荷。如果添加有效负载,则必须使用@RequestBody。在这里你必须使用@RequestParam。在控制器中使用以下代码:


public ResponseEntity<String> authenticate(@RequestParam String email, @RequestParam String password, HttpServletRequest request,HttpServletResponse response){

 ..do stuff

}

这将工作..!


查看完整回答
反对 回复 2021-11-24
  • 3 回答
  • 0 关注
  • 281 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信