|
@ -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==
|
|
|
}
|
|
|
}
|