package com.mzl.flower.config.security.handler; import cn.hutool.core.map.MapUtil; import com.fasterxml.jackson.databind.ObjectMapper; import com.mzl.flower.base.R; import com.mzl.flower.base.ReturnDataDTO; import com.mzl.flower.config.security.AuthUtils; import lombok.Builder; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpHeaders; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.exceptions.InvalidClientException; import org.springframework.security.oauth2.common.exceptions.UnapprovedClientAuthenticationException; import org.springframework.security.oauth2.provider.*; import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Slf4j @Builder public class SelfAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { private static final String BASIC_ = "Basic "; private PasswordEncoder passwordEncoder; private ObjectMapper objectMapper; private ClientDetailsService clientDetailsService; private AuthorizationServerTokenServices authorizationServerTokenServices; @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { 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]; String clientSecret = tokens[1]; ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId); //校验secret if (!passwordEncoder.matches(clientSecret, clientDetails.getClientSecret())) { throw new InvalidClientException("Given client ID does not match authenticated client"); } TokenRequest tokenRequest = new TokenRequest(MapUtil.newHashMap(), clientId, clientDetails.getScope(), "password"); OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails); OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication); OAuth2AccessToken token = authorizationServerTokenServices.createAccessToken(oAuth2Authentication); response.setContentType("application/json;charset=UTF-8"); ReturnDataDTO resultDTO = new ReturnDataDTO(R.SUCCESS.getCode(), token, "success"); response.getWriter().write(objectMapper.writeValueAsString(resultDTO)); } catch (IOException e) { throw new BadCredentialsException( "Failed to decode basic authentication token"); } catch (Exception e) { throw new BadCredentialsException(e.getMessage()); } } }