Spring Security开发调试记录

Spring Security+jwt开发调试记录

首先需要在工程的websecurityconfig文件中添加这样一个注解

由于问题出在密码正确却无法登录,因此从认证方面找原因,选择在attemptAuthentication函数中设置断点在这里插入图片描述
可以看到拦截器顺利的获取到了来自于前端的信息,这至少证明,来自于前端的信息是没有问题的,接着往下走。
在这一行stepinto
在这里插入图片描述
这句话的意思是获取当前的一个authenticationManager变量并调用其中的authenticate()函数,查看一下authenticationManager变量的具体数据
在这里插入图片描述
再看一下authenticate()函数的具体实现
在这里插入图片描述
进去之后才发现是一个接口,查看一下他的具体实现,
在这里插入图片描述
这里我们要看的是security目录下的内容,进入ProviderManager查看实现

public Authentication authenticate(Authentication authentication)
			throws AuthenticationException {
		Class<? extends Authentication> toTest = authentication.getClass();
		AuthenticationException lastException = null;
		AuthenticationException parentException = null;
		Authentication result = null;
		Authentication parentResult = null;
		boolean debug = logger.isDebugEnabled();

		for (AuthenticationProvider provider : getProviders()) {
			if (!provider.supports(toTest)) {
				continue;
			}

			if (debug) {
				logger.debug("Authentication attempt using "
						+ provider.getClass().getName());
			}

			try {
				result = provider.authenticate(authentication);

				if (result != null) {
					copyDetails(authentication, result);
					break;
				}
			}
			catch (AccountStatusException | InternalAuthenticationServiceException e) {
				prepareException(e, authentication);
				// SEC-546: Avoid polling additional providers if auth failure is due to
				// invalid account status
				throw e;
			} catch (AuthenticationException e) {
				lastException = e;
			}
		}

		if (result == null && parent != null) {
			// Allow the parent to try.
			try {
				result = parentResult = parent.authenticate(authentication);
			}
			catch (ProviderNotFoundException e) {
				// ignore as we will throw below if no other exception occurred prior to
				// calling parent and the parent
				// may throw ProviderNotFound even though a provider in the child already
				// handled the request
			}
			catch (AuthenticationException e) {
				lastException = parentException = e;
			}
		}

		if (result != null) {
			if (eraseCredentialsAfterAuthentication
					&& (result instanceof CredentialsContainer)) {
				// Authentication is complete. Remove credentials and other secret data
				// from authentication
				((CredentialsContainer) result).eraseCredentials();
			}

			// If the parent AuthenticationManager was attempted and successful than it will publish an AuthenticationSuccessEvent
			// This check prevents a duplicate AuthenticationSuccessEvent if the parent AuthenticationManager already published it
			if (parentResult == null) {
				eventPublisher.publishAuthenticationSuccess(result);
			}
			return result;
		}

		// Parent was null, or didn't authenticate (or throw an exception).

		if (lastException == null) {
			lastException = new ProviderNotFoundException(messages.getMessage(
					"ProviderManager.providerNotFound",
					new Object[] { toTest.getName() },
					"No AuthenticationProvider found for {0}"));
		}

		// If the parent AuthenticationManager was attempted and failed than it will publish an AbstractAuthenticationFailureEvent
		// This check prevents a duplicate AbstractAuthenticationFailureEvent if the parent AuthenticationManager already published it
		if (parentException == null) {
			prepareException(lastException, authentication);
		}

		throw lastException;
	}

从源码中我们可以看到providers是非常重要的一个成员变量,这个函数通过遍历列表里的一个个provider,判断它是否支持参数authentication的认证,这里我们就可以回去看一下authenticationManager变量的的providers究竟有哪些,
在这里插入图片描述
里面只有一项内容查阅该类的相关资料,可知这个类并不指出usernamepassword形式的authentication
难道是这里出错了?
阅读完代码后继续运行
在这里插入图片描述
这一步在意料之中,接着往下运行
在这里插入图片描述
原来除了判断自身的provider之外还需要调用parent元素中的authenticate()函数,查看parent里面的provider
在这里插入图片描述
可以看到parent里面的provider是可以支持认证的
接着运行可以看到调用了provider的authenticate()函数
在这里插入图片描述
在这里插入图片描述
继续stepinto查看user是如何获得的。
在这里插入图片描述
看到了获取Userdetail的函数loadUserByUsername
在这里插入图片描述
就是在这里出了问题,本来这个函数应该调用我自己书写的UserDetailsServiceImp结果却去到了另一个实现类,我判断是因为我的UserDetailsServiceImp没有被识别于是会去检查了一下代码,发现少了一个@Service注释。。。。。。。。
加上去之后问题解决
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值