登录成后返回 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();
}
}