|  | @ -0,0 +1,121 @@
 | 
	
		
			
				|  |  | /**
 | 
	
		
			
				|  |  |  *
 | 
	
		
			
				|  |  |  */
 | 
	
		
			
				|  |  | package com.yihu.base.security.hander;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | import com.fasterxml.jackson.databind.ObjectMapper;
 | 
	
		
			
				|  |  | import org.apache.commons.codec.binary.StringUtils;
 | 
	
		
			
				|  |  | import org.apache.commons.collections.MapUtils;
 | 
	
		
			
				|  |  | import org.slf4j.Logger;
 | 
	
		
			
				|  |  | import org.slf4j.LoggerFactory;
 | 
	
		
			
				|  |  | import org.springframework.beans.factory.annotation.Autowired;
 | 
	
		
			
				|  |  | import org.springframework.security.authentication.BadCredentialsException;
 | 
	
		
			
				|  |  | import org.springframework.security.core.Authentication;
 | 
	
		
			
				|  |  | import org.springframework.security.crypto.codec.Base64;
 | 
	
		
			
				|  |  | import org.springframework.security.oauth2.common.OAuth2AccessToken;
 | 
	
		
			
				|  |  | 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 org.springframework.stereotype.Component;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | import javax.servlet.ServletException;
 | 
	
		
			
				|  |  | import javax.servlet.http.HttpServletRequest;
 | 
	
		
			
				|  |  | import javax.servlet.http.HttpServletResponse;
 | 
	
		
			
				|  |  | import java.io.IOException;
 | 
	
		
			
				|  |  | import java.io.UnsupportedEncodingException;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | /**
 | 
	
		
			
				|  |  |  * @author chenweida
 | 
	
		
			
				|  |  |  * <p>
 | 
	
		
			
				|  |  |  * 账号密码提交需要在 head 中添加 Basic clientID:cliengSecurty
 | 
	
		
			
				|  |  |  */
 | 
	
		
			
				|  |  | @Component("BaseAuthenticationSuccessHandler")
 | 
	
		
			
				|  |  | public class BaseAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private Logger logger = LoggerFactory.getLogger(getClass());
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private ObjectMapper objectMapper = new ObjectMapper();
 | 
	
		
			
				|  |  |     @Autowired
 | 
	
		
			
				|  |  |     private ClientDetailsService clientDetailsService;
 | 
	
		
			
				|  |  |     @Autowired
 | 
	
		
			
				|  |  |     private AuthorizationServerTokenServices authorizationServerTokenServices;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     /*
 | 
	
		
			
				|  |  |      * (non-Javadoc)
 | 
	
		
			
				|  |  |      *
 | 
	
		
			
				|  |  |      * @see org.springframework.security.web.authentication.
 | 
	
		
			
				|  |  |      * AuthenticationSuccessHandler#onAuthenticationSuccess(javax.servlet.http.
 | 
	
		
			
				|  |  |      * HttpServletRequest, javax.servlet.http.HttpServletResponse,
 | 
	
		
			
				|  |  |      * org.springframework.security.core.Authentication)
 | 
	
		
			
				|  |  |      */
 | 
	
		
			
				|  |  |     @Override
 | 
	
		
			
				|  |  |     public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
 | 
	
		
			
				|  |  |                                         Authentication authentication) throws IOException, ServletException {
 | 
	
		
			
				|  |  |         String header = request.getHeader("Authorization");
 | 
	
		
			
				|  |  |         if (header != null && header.startsWith("Basic ")) {
 | 
	
		
			
				|  |  |             throw new UnapprovedClientAuthenticationException("请求头没有client信息");
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         //解析头部的basic信息
 | 
	
		
			
				|  |  |         String[] tokens = extractAndDecodeHeader(header, request);
 | 
	
		
			
				|  |  |         assert tokens.length == 2;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         String clientId = tokens[0];
 | 
	
		
			
				|  |  |         String clientSecurity = tokens[1];
 | 
	
		
			
				|  |  |         //得到ClientDetails
 | 
	
		
			
				|  |  |         ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         if (clientDetails == null) {
 | 
	
		
			
				|  |  |             throw new UnapprovedClientAuthenticationException("clientId不存在 client:" + clientId);
 | 
	
		
			
				|  |  |         } else if (!StringUtils.equals(clientDetails.getClientSecret(), clientSecurity)) {
 | 
	
		
			
				|  |  |             throw new UnapprovedClientAuthenticationException("clientSecurity 不匹配 client:" + clientId);
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         TokenRequest tokenRequest = new TokenRequest(MapUtils.EMPTY_MAP, clientId, clientDetails.getScope(), "custom_password");
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         OAuth2AccessToken token = authorizationServerTokenServices.createAccessToken(oAuth2Authentication);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         response.setContentType("application/json;charset=UTF-8");
 | 
	
		
			
				|  |  |         response.getWriter().write(objectMapper.writeValueAsString(token));
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     /**
 | 
	
		
			
				|  |  |      * 解析
 | 
	
		
			
				|  |  |      *
 | 
	
		
			
				|  |  |      * @param header
 | 
	
		
			
				|  |  |      * @param request
 | 
	
		
			
				|  |  |      * @return
 | 
	
		
			
				|  |  |      * @throws IOException
 | 
	
		
			
				|  |  |      */
 | 
	
		
			
				|  |  |     private String[] extractAndDecodeHeader(String header, HttpServletRequest request)
 | 
	
		
			
				|  |  |             throws IOException {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         byte[] base64Token = header.substring(6).getBytes("UTF-8");
 | 
	
		
			
				|  |  |         byte[] decoded;
 | 
	
		
			
				|  |  |         try {
 | 
	
		
			
				|  |  |             decoded = Base64.decode(base64Token);
 | 
	
		
			
				|  |  |         } catch (IllegalArgumentException e) {
 | 
	
		
			
				|  |  |             throw new BadCredentialsException(
 | 
	
		
			
				|  |  |                     "Failed to decode basic authentication token");
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         String token = new String(decoded, "UTF-8");
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         int delim = token.indexOf(":");
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         if (delim == -1) {
 | 
	
		
			
				|  |  |             throw new BadCredentialsException("Basic 信息不合法");
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         return new String[]{token.substring(0, delim), token.substring(delim + 1)};
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     public static void main(String[] args) throws UnsupportedEncodingException {
 | 
	
		
			
				|  |  |         System.out.println(new String(Base64.encode("cwd:cwd".getBytes()), "UTF-8"));//   Y3dkOmN3ZA==
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | }
 |