V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
AchillesNeo
V2EX  ›  问与答

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

  •  
  •   AchillesNeo · 2020-06-04 16:39:27 +08:00 · 1354 次点击
    这是一个创建于 1432 天前的主题,其中的信息可能已经有所发展或是发生改变。

    登录成后返回 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();
    	}
    }
    
    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1048 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 19:30 · PVG 03:30 · LAX 12:30 · JFK 15:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.