123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- /**
- *
- */
- package com.yihu.base.security.hander;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.yihu.base.security.properties.SecurityProperties;
- import com.yihu.base.security.rbas.ClientServiceProvider;
- import com.yihu.base.security.sms.process.SmsValidateCodeProcessor;
- 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.beans.factory.annotation.Qualifier;
- import org.springframework.security.authentication.BadCredentialsException;
- import org.springframework.security.core.Authentication;
- import org.springframework.security.crypto.codec.Base64;
- import org.springframework.security.crypto.password.PasswordEncoder;
- 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.oauth2.provider.token.DefaultTokenServices;
- import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
- import org.springframework.stereotype.Component;
- import org.springframework.util.AntPathMatcher;
- import org.springframework.web.context.request.ServletWebRequest;
- import javax.annotation.Resource;
- 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());
- /**
- * 验证请求url与配置的url是否匹配的工具类
- */
- private AntPathMatcher pathMatcher = new AntPathMatcher();
- @Autowired
- private ObjectMapper objectMapper;
- @Autowired
- private ClientServiceProvider clientDetailsService;
- @Autowired
- private AuthorizationServerTokenServices defaultTokenServices;
- @Autowired
- private SmsValidateCodeProcessor smsValidateCodeProcessor;
- @Autowired
- private PasswordEncoder passwordEncoder;
- /*
- * (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 (org.springframework.util.StringUtils.isEmpty(header) || (!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(clientSecurity,clientDetails.getClientSecret())) {
- 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 = defaultTokenServices.createAccessToken(oAuth2Authentication);
- if(pathMatcher.match(SecurityProperties.mobileLogin, request.getRequestURI())){
- //验证码模式登陆,说明登陆成功 删除验证码
- smsValidateCodeProcessor.reomve(new ServletWebRequest(request,response));
- }
- 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)};
- }
- }
|