BaseAuthenticationSuccessHandler.java 5.7 KB

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