spring boot + oauth2 ClientDetailsService 一直是空怎么回事?

2020-06-04 16:39:27 +08:00
 AchillesNeo

登录成后返回 token 信息 token 由 oauth2 生成创建。可是在验证成功后一直无法生成 token ClientDetailsService 对象一直是空的不知道什么回事。有谁遇到过?求解。

SecurityConfig.java 配置

@Override
	protected void configure(HttpSecurity http) throws Exception {
		// @formatter:off
		http.headers()
			.frameOptions()
			.disable();

		http.authorizeRequests()
			.antMatchers("/actuator/**",
				"/oauth/removeToken",
				"/oauth/delToken/*",
				"/oauth/listToken",
				"/mobile/**").permitAll()
			.anyRequest()
			.authenticated();

		http.exceptionHandling()
			.accessDeniedHandler(new DreamAccessDeniedHandler("/accessDenied"));

		http.formLogin()
			.loginPage("/login")
//			.loginProcessingUrl("/session")
			.loginProcessingUrl("/auth/oauth/token")
			.failureHandler(authFailureEvenHandler)
			.successHandler(authSuccessEvenHandler)
			.authenticationDetailsSource(authDetailsSource)
			.permitAll();


		http.rememberMe()
			.tokenRepository(rememberMeTokenRepository())
			.userDetailsService(userDetailsService)
			.tokenValiditySeconds(30 * 24 * 60);

		http.logout()
			.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
			.logoutSuccessUrl("/")
			.deleteCookies("JSESSIONID", "remember-me");

		http.csrf()
			.ignoringAntMatchers("/druid/**", "/ueditor")
			.csrfTokenRepository(new CookieCsrfTokenRepository())
			.disable();
		// @formatter:on
	}

DreamAuthSuccessEvenHandler.java authSuccessEvenHandler 具体实现代码 debug 在 System.out.println(" clientDetailsService "+clientDetailsService); 打印内容为空问题点是为什么一直为空?

@Slf4j
@Component
@RequiredArgsConstructor
//@Builder
public class DreamAuthSuccessEvenHandler implements AuthenticationSuccessHandler {
//	private final ApplicationEventPublisher publisher;
//	private final MessageSource messageSource;



	private static final String BASIC_ = "Basic ";
	private ObjectMapper objectMapper;
	private PasswordEncoder passwordEncoder;
	private ClientDetailsService clientDetailsService;

	private PigClientDetailsService pigClientDetailsService;
	private AuthorizationServerTokenServices defaultAuthorizationServerTokenServices;


	@Override
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
			Authentication authentication) throws IOException, ServletException {
//		WebUtil.renderJson(response, R.success());
		// 记录登录日志
		SysLogEvent sysLogEvent = SysLogUtils.getSysLogDTO();
		sysLogEvent.setOperation("登录成功");
		sysLogEvent.setClassMethod("net.dreamlu.secrity.auth.DreamAuthHandler.onAuthenticationSuccess();");
		// 发送 spring event 事件
//		publisher.publishEvent(sysLogEvent);
		log.info("用户:{} 登录成功", authentication.getPrincipal());
//		R<String> result = R.success("登录成功");
//		WebUtil.renderJson(response, result);


		String header = request.getHeader(HttpHeaders.AUTHORIZATION);

		if (header == null || !header.startsWith(BASIC_)) {
			throw new UnapprovedClientAuthenticationException("请求头中 client 信息为空");
		}

		try {
			String[] tokens = AuthUtils.extractAndDecodeHeader(header);
			assert tokens.length == 2;
			String clientId = tokens[0];

			System.out.println(" clientId "+clientId);
			System.out.println(" clientDetailsService "+clientDetailsService);



			ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);

			//校验 secret
			if (!passwordEncoder.matches(tokens[1], clientDetails.getClientSecret())) {
				throw new InvalidClientException("Given client ID does not match authenticated client");

			}

			TokenRequest tokenRequest = new TokenRequest(MapUtil.newHashMap(), clientId, clientDetails.getScope(), "mobile");

			//校验 scope
			new DefaultOAuth2RequestValidator().validateScope(tokenRequest, clientDetails);
			OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);
			OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);
			OAuth2AccessToken oAuth2AccessToken = defaultAuthorizationServerTokenServices.createAccessToken(oAuth2Authentication);
			log.info("获取 token 成功:{}", oAuth2AccessToken.getValue());

			response.setCharacterEncoding(CharsetUtil.UTF_8);
			response.setContentType(CommonConstants.CONTENT_TYPE);
//			PrintWriter printWriter = response.getWriter();
//			printWriter.append(objectMapper.writeValueAsString(oAuth2AccessToken));

			WebUtil.renderJson(response, objectMapper.writeValueAsString(oAuth2AccessToken));

		} catch (IOException e) {
			throw new BadCredentialsException(
				"Failed to decode basic authentication token");
		}

	}



	/**
	 * https://spring.io/blog/2017/11/01/spring-security-5-0-0-rc1-released#password-storage-updated
	 * Encoded password does not look like BCrypt
	 *
	 * @return PasswordEncoder
	 */
	@Bean
	public PasswordEncoder passwordEncoder() {
		return PasswordEncoderFactories.createDelegatingPasswordEncoder();
	}
}
1450 次点击
所在节点    问与答
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/678640

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX