|
@@ -0,0 +1,210 @@
|
|
|
|
+package com.jeesharp.modules.api.sys.security;
|
|
|
|
+
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
|
+import com.jeesharp.common.constant.ResponseCode;
|
|
|
|
+import com.jeesharp.common.json.ServerResponse;
|
|
|
|
+import com.jeesharp.common.mapper.JsonMapper;
|
|
|
|
+import com.jeesharp.common.utils.StringUtils;
|
|
|
|
+import com.jeesharp.modules.api.sys.util.MobileUtils;
|
|
|
|
+import com.jeesharp.modules.sys.utils.UserUtils;
|
|
|
|
+import com.jeesharp.shiro.Principal;
|
|
|
|
+import com.jeesharp.shiro.constant.ShiroConstant;
|
|
|
|
+import org.apache.shiro.authc.*;
|
|
|
|
+import org.apache.shiro.web.util.WebUtils;
|
|
|
|
+import org.slf4j.Logger;
|
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
|
+import org.springframework.http.HttpStatus;
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
+import org.springframework.web.bind.annotation.RequestMethod;
|
|
|
|
+
|
|
|
|
+import javax.servlet.ServletRequest;
|
|
|
|
+import javax.servlet.ServletResponse;
|
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
|
+import java.io.IOException;
|
|
|
|
+import java.io.PrintWriter;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+@Service
|
|
|
|
+public class SysApiAuthenticationFilter extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter {
|
|
|
|
+
|
|
|
|
+ public static final String DEFAULT_CAPTCHA_PARAM = "validateCode";
|
|
|
|
+ public static final String DEFAULT_MOBILE_PARAM = "mobileLogin";
|
|
|
|
+ public static final String DEFAULT_MESSAGE_PARAM = "message";
|
|
|
|
+
|
|
|
|
+ private String captchaParam = DEFAULT_CAPTCHA_PARAM;
|
|
|
|
+ private String mobileLoginParam = DEFAULT_MOBILE_PARAM;
|
|
|
|
+ private String messageParam = DEFAULT_MESSAGE_PARAM;
|
|
|
|
+
|
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(SysApiAuthenticationFilter.class);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 对跨域提供支持
|
|
|
|
+ */
|
|
|
|
+ @Override
|
|
|
|
+ protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
|
|
|
|
+ HttpServletRequest httpServletRequest = (HttpServletRequest) request;
|
|
|
|
+ HttpServletResponse httpServletResponse = (HttpServletResponse) response;
|
|
|
|
+ httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
|
|
|
|
+ httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
|
|
|
|
+ httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
|
|
|
|
+ // 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态
|
|
|
|
+ if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
|
|
|
|
+ httpServletResponse.setStatus(HttpStatus.OK.value());
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ return super.preHandle(request, response);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
|
|
|
|
+ String pa = request.getParameter("password");
|
|
|
|
+ String username = getUsername(request);
|
|
|
|
+ String password = getPassword(request);
|
|
|
|
+ if (password == null) {
|
|
|
|
+ password = "";
|
|
|
|
+ }
|
|
|
|
+ boolean rememberMe = isRememberMe(request);
|
|
|
|
+ String host = StringUtils.getRemoteAddr((HttpServletRequest) request);
|
|
|
|
+ String captcha = getCaptcha(request);
|
|
|
|
+ boolean mobile = isMobileLogin(request);
|
|
|
|
+ return new com.jeesharp.modules.sys.security.UsernamePasswordToken(username, password.toCharArray(), rememberMe, host,captcha ,mobile);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public String getCaptchaParam() {
|
|
|
|
+ return captchaParam;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ protected String getCaptcha(ServletRequest request) {
|
|
|
|
+ return WebUtils.getCleanParam(request, getCaptchaParam());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public String getMobileLoginParam() {
|
|
|
|
+ return mobileLoginParam;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ protected boolean isMobileLogin(ServletRequest request) {
|
|
|
|
+ return WebUtils.isTrue(request, getMobileLoginParam());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public String getMessageParam() {
|
|
|
|
+ return messageParam;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void setLoginUrl(String loginUrl) {
|
|
|
|
+ super.setLoginUrl("/apiSys/login");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 重写登录地址
|
|
|
|
+ */
|
|
|
|
+ @Override
|
|
|
|
+ protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException {
|
|
|
|
+ HttpServletRequest req = (HttpServletRequest) request;
|
|
|
|
+ if (MobileUtils.checkAgentIsMobile(req.getHeader("user-agent"))) {
|
|
|
|
+ write((HttpServletResponse) response, ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),
|
|
|
|
+ ResponseCode.NEED_LOGIN.getName()));
|
|
|
|
+ } else {
|
|
|
|
+ WebUtils.issueRedirect(request, response, "/api/sys/login");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 登录失败调用事件
|
|
|
|
+ */
|
|
|
|
+ @Override
|
|
|
|
+ protected boolean onLoginFailure(AuthenticationToken token,
|
|
|
|
+ AuthenticationException e, ServletRequest request, ServletResponse response) {
|
|
|
|
+ String className = e.getClass().getName(), message = "";
|
|
|
|
+ if (IncorrectCredentialsException.class.getName().equals(className)
|
|
|
|
+ || UnknownAccountException.class.getName().equals(className)) {
|
|
|
|
+ message = "用户或密码错误, 请重试.";
|
|
|
|
+ } else if (e.getMessage() != null && StringUtils.startsWith(e.getMessage(), "msg:")) {
|
|
|
|
+ message = StringUtils.replace(e.getMessage(), "msg:", "");
|
|
|
|
+ } else {
|
|
|
|
+ message = "系统出现点问题,请稍后再试!";
|
|
|
|
+ e.printStackTrace(); // 输出到控制台
|
|
|
|
+ }
|
|
|
|
+ write((HttpServletResponse) response, ServerResponse.createByErrorMessge(message));
|
|
|
|
+ request.setAttribute(getFailureKeyAttribute(), className);
|
|
|
|
+ request.setAttribute(getMessageParam(), message);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ protected void issueSuccessRedirect(ServletRequest request,
|
|
|
|
+ ServletResponse response) throws Exception {
|
|
|
|
+ Principal principal = UserUtils.getPrincipal();
|
|
|
|
+ JSONObject jsonObject = new JSONObject();
|
|
|
|
+ jsonObject.put("token", principal.getSessionid());
|
|
|
|
+ jsonObject.put("user", UserUtils.getUser());
|
|
|
|
+ // jsonObject.put("company",UserUtils.getCompany());
|
|
|
|
+ write((HttpServletResponse) response, ServerResponse.createBySuccess(jsonObject));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ protected boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
|
|
|
|
+ if (this.isLoginRequest(request, response)) {
|
|
|
|
+ if (this.isLoginSubmission(request, response)) {
|
|
|
|
+ if (log.isTraceEnabled()) {
|
|
|
|
+ log.trace("Login submission detected. Attempting to execute login.");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return this.executeLogin(request, response);
|
|
|
|
+ } else {
|
|
|
|
+ if (log.isTraceEnabled()) {
|
|
|
|
+ log.trace("Login page view.");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ if (log.isTraceEnabled()) {
|
|
|
|
+ log.trace("Attempting to access a path which requires authentication. Forwarding to the Authentication url [" + this.getLoginUrl() + "]");
|
|
|
|
+ }
|
|
|
|
+ if (((HttpServletRequest)request).getRequestURI().startsWith(ShiroConstant.REQUEST_API_SYS_URL)) {
|
|
|
|
+ write((HttpServletResponse) response,ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),
|
|
|
|
+ ResponseCode.NEED_LOGIN.getName()));
|
|
|
|
+ } else {
|
|
|
|
+ this.saveRequestAndRedirectToLogin(request, response);
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ public static void write(HttpServletResponse response,String content) {
|
|
|
|
+ response.reset();
|
|
|
|
+ response.setContentType("application/json");
|
|
|
|
+ response.setHeader("Cache-Control", "no-store");
|
|
|
|
+ response.setCharacterEncoding("UTF-8");
|
|
|
|
+ try {
|
|
|
|
+ PrintWriter pw=response.getWriter();
|
|
|
|
+ pw.write(content);
|
|
|
|
+ pw.flush();
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static void write(HttpServletResponse response,Object object) {
|
|
|
|
+ response.reset();
|
|
|
|
+ response.setContentType("application/json");
|
|
|
|
+ response.setHeader("Cache-Control", "no-store");
|
|
|
|
+ response.setCharacterEncoding("UTF-8");
|
|
|
|
+ try {
|
|
|
|
+ PrintWriter pw=response.getWriter();
|
|
|
|
+ pw.write(JsonMapper.toJsonString(object));
|
|
|
|
+ pw.flush();
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|