BaseAuthenticationSuccessHandler.java 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /**
  2. *
  3. */
  4. package com.yihu.base.security.hander;
  5. import com.fasterxml.jackson.databind.ObjectMapper;
  6. import org.apache.commons.codec.binary.StringUtils;
  7. import org.apache.commons.collections.MapUtils;
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.security.authentication.BadCredentialsException;
  12. import org.springframework.security.core.Authentication;
  13. import org.springframework.security.crypto.codec.Base64;
  14. import org.springframework.security.oauth2.common.OAuth2AccessToken;
  15. import org.springframework.security.oauth2.common.exceptions.UnapprovedClientAuthenticationException;
  16. import org.springframework.security.oauth2.provider.*;
  17. import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
  18. import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
  19. import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
  20. import org.springframework.stereotype.Component;
  21. import javax.servlet.ServletException;
  22. import javax.servlet.http.HttpServletRequest;
  23. import javax.servlet.http.HttpServletResponse;
  24. import java.io.IOException;
  25. import java.io.UnsupportedEncodingException;
  26. /**
  27. * @author chenweida
  28. * <p>
  29. * 账号密码提交需要在 head 中添加 Basic clientID:cliengSecurty
  30. */
  31. @Component("BaseAuthenticationSuccessHandler")
  32. public class BaseAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
  33. private Logger logger = LoggerFactory.getLogger(getClass());
  34. private ObjectMapper objectMapper = new ObjectMapper();
  35. @Autowired
  36. private ClientDetailsService clientDetailsService;
  37. @Autowired
  38. private AuthorizationServerTokenServices defaultTokenServices;
  39. /*
  40. * (non-Javadoc)
  41. *
  42. * @see org.springframework.security.web.authentication.
  43. * AuthenticationSuccessHandler#onAuthenticationSuccess(javax.servlet.http.
  44. * HttpServletRequest, javax.servlet.http.HttpServletResponse,
  45. * org.springframework.security.core.Authentication)
  46. */
  47. @Override
  48. public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
  49. Authentication authentication) throws IOException, ServletException {
  50. String header = request.getHeader("Authorization");
  51. if (org.springframework.util.StringUtils.isEmpty(header) ||(! header.startsWith("Basic "))) {
  52. throw new UnapprovedClientAuthenticationException("请求头没有client信息");
  53. }
  54. //解析头部的basic信息
  55. String[] tokens = extractAndDecodeHeader(header, request);
  56. assert tokens.length == 2;
  57. String clientId = tokens[0];
  58. String clientSecurity = tokens[1];
  59. //得到ClientDetails
  60. ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);
  61. if (clientDetails == null) {
  62. throw new UnapprovedClientAuthenticationException("clientId不存在 client:" + clientId);
  63. } else if (!StringUtils.equals(clientDetails.getClientSecret(), clientSecurity)) {
  64. throw new UnapprovedClientAuthenticationException("clientSecurity 不匹配 client:" + clientId);
  65. }
  66. TokenRequest tokenRequest = new TokenRequest(MapUtils.EMPTY_MAP, clientId, clientDetails.getScope(), "custom_password");
  67. OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);
  68. OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);
  69. OAuth2AccessToken token = defaultTokenServices.createAccessToken(oAuth2Authentication);
  70. response.setContentType("application/json;charset=UTF-8");
  71. response.getWriter().write(objectMapper.writeValueAsString(token));
  72. }
  73. /**
  74. * 解析
  75. *
  76. * @param header
  77. * @param request
  78. * @return
  79. * @throws IOException
  80. */
  81. private String[] extractAndDecodeHeader(String header, HttpServletRequest request)
  82. throws IOException {
  83. byte[] base64Token = header.substring(6).getBytes("UTF-8");
  84. byte[] decoded;
  85. try {
  86. decoded = Base64.decode(base64Token);
  87. } catch (IllegalArgumentException e) {
  88. throw new BadCredentialsException(
  89. "Failed to decode basic authentication token");
  90. }
  91. String token = new String(decoded, "UTF-8");
  92. int delim = token.indexOf(":");
  93. if (delim == -1) {
  94. throw new BadCredentialsException("Basic 信息不合法");
  95. }
  96. return new String[]{token.substring(0, delim), token.substring(delim + 1)};
  97. }
  98. public static void main(String[] args) throws UnsupportedEncodingException {
  99. System.out.println(new String(Base64.encode("cwd:cwd".getBytes()), "UTF-8"));// Y3dkOmN3ZA==
  100. }
  101. }