parent
36db7fa387
commit
d5dcc8285d
|
|
@ -7,11 +7,12 @@ import com.ruoyi.common.annotation.Log;
|
|||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
|
@ -24,16 +25,16 @@ import java.io.IOException;
|
|||
* @author box
|
||||
* @date 2021-05-13
|
||||
*/
|
||||
@Api("快递信息订阅推送")
|
||||
@Api(value = "快递信息订阅推送",tags = "快递订阅接口")
|
||||
@RestController
|
||||
@RequestMapping("/anon")
|
||||
/*@RequestMapping("/anon")*/
|
||||
public class ExpSubsPushApiController extends BaseController {
|
||||
@Autowired
|
||||
IExpSubsPushApiService expSubsPushApiService;
|
||||
|
||||
//推送
|
||||
@CrossOrigin
|
||||
@PostMapping("/subscribeCallBackUrl")
|
||||
@PostMapping("anon/subscribeCallBackUrl")
|
||||
@ApiOperation("快递信息订阅推送接受")
|
||||
public SubscribeResp SubscribeCallBackUrl(HttpServletRequest request) {
|
||||
return expSubsPushApiService.ExpressSubscribeCallBackUrl(request);
|
||||
|
|
@ -41,16 +42,22 @@ public class ExpSubsPushApiController extends BaseController {
|
|||
|
||||
//订阅
|
||||
@CrossOrigin
|
||||
@PostMapping("/subscribe")
|
||||
@PostMapping("anon/subscribe")
|
||||
public SubscribeResp Subscribe(ExpSubscribe expSubscribe){
|
||||
return expSubsPushApiService.ExpressSubscribe(expSubscribe);
|
||||
}
|
||||
|
||||
//接受ERP订阅,
|
||||
//接受topgp订阅,
|
||||
@Log(title = "快递订阅", businessType = BusinessType.OTHER)
|
||||
@CrossOrigin
|
||||
@PostMapping("/topgpExpressSubscribe")
|
||||
public String topgpSubscribe(HttpServletRequest request,HttpServletResponse response) throws IOException {
|
||||
@ApiOperation(value="topgp订阅快递",notes = "request body格式: {\"deliveryNo\":\"S301-2108020001\",\"expressNo\":\"300444235610\",\"company\":\"annengwuliu\",\"phone\":\"13800138000\"}")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "token", value = "token", required = true, paramType = "header", dataType = "String", dataTypeClass = String.class),
|
||||
@ApiImplicitParam(name = "requestJson", value = "请求json",required = true, paramType = "body", dataType = "String", dataTypeClass = String.class)
|
||||
})
|
||||
|
||||
@PostMapping("api/express/topgpSubscribe")
|
||||
public String topgpSubscribe(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
return expSubsPushApiService.ExpressSubscribeWithTopgp(request);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,34 +7,39 @@ import com.ruoyi.common.core.domain.AjaxResult;
|
|||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.enums.DataSourceType;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Api(tags = "TOPGP使用帆软报表接口")
|
||||
@RestController
|
||||
public class FrForCrTopgpController {
|
||||
@Autowired
|
||||
private TopgpDdlService topgpDdlService;
|
||||
|
||||
//访问 ../anon/bps/frforcr/topprod时,使用topprod
|
||||
@ApiOperation("TOPPROD正式区访问")
|
||||
@ApiImplicitParam(name = "jsonString", value = "Json字符串", paramType = "body", dataType = "String", dataTypeClass = String.class)
|
||||
@CrossOrigin
|
||||
@Log(title = "CSFR412_CR报表_TOPPROD", businessType = BusinessType.DROP)
|
||||
@RequestMapping("/anon/bps/frforcr/topprod")
|
||||
@PostMapping("/anon/bps/frforcr/topprod")
|
||||
@DataSource(value = DataSourceType.TOPPRODDSREPORT)
|
||||
public AjaxResult frforcrtopprod(@RequestBody Map<String,Object> map){
|
||||
return frforcrtoppgp(map);
|
||||
}
|
||||
|
||||
//访问../anon/bps/frforcr/topprod时,使用toptest实例
|
||||
@ApiOperation("TOPTEST正式区访问")
|
||||
@ApiImplicitParam(name = "jsonString", value = "Json字符串", paramType = "body", dataType = "String", dataTypeClass = String.class)
|
||||
@CrossOrigin
|
||||
@Log(title = "CSFR412_CR报表_TOPTEST", businessType = BusinessType.DROP)
|
||||
@RequestMapping("/anon/bps/frforcr/toptest")
|
||||
@PostMapping("/anon/bps/frforcr/toptest")
|
||||
@DataSource(value = DataSourceType.TOPTESTDSREPORT)
|
||||
public AjaxResult frforcrtoptest(@RequestBody Map<String,Object> map){
|
||||
return frforcrtoppgp(map);
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ public class ExpSubsPushApiServiceImpl implements IExpSubsPushApiService {
|
|||
str+="\r\n";
|
||||
}
|
||||
}
|
||||
System.out.println(str);
|
||||
//System.out.println(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
|
@ -287,7 +287,7 @@ public class ExpSubsPushApiServiceImpl implements IExpSubsPushApiService {
|
|||
//todo
|
||||
|
||||
//返回错误信息
|
||||
return map.toString();
|
||||
return JSONObject.toJSONString(map);
|
||||
|
||||
}
|
||||
//向快递100推送订阅请求
|
||||
|
|
@ -302,7 +302,7 @@ public class ExpSubsPushApiServiceImpl implements IExpSubsPushApiService {
|
|||
Map map=JSONObject.parseObject(object.toString(), Map.class);
|
||||
map.put("deliveryNo",deliveryNo);
|
||||
map.put("expressNo",expressNo);
|
||||
return map.toString();
|
||||
return JSONObject.toJSONString(map);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,37 @@
|
|||
package com.ruoyi.web.controller.system;
|
||||
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.utils.ServletUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ruoyi.common.utils.http.HttpUtils;
|
||||
import com.ruoyi.framework.jwt.service.IJwtTokenService;
|
||||
import com.ruoyi.framework.shiro.util.CustToken;
|
||||
import com.ruoyi.system.service.IWechatApiService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.enums.UserStatus;
|
||||
import com.ruoyi.common.utils.ServletUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.framework.jwt.utils.JwtUtils;
|
||||
import com.ruoyi.framework.shiro.service.SysPasswordService;
|
||||
import com.ruoyi.system.service.ISysUserService;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
|
@ -24,9 +39,13 @@ import java.util.Map;
|
|||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Api(tags = "生成AccessToken接口")
|
||||
@Controller
|
||||
public class SysLoginController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IJwtTokenService jwtTokenService;
|
||||
|
||||
@Autowired
|
||||
private IWechatApiService wechatApiService;
|
||||
|
||||
|
|
@ -83,6 +102,26 @@ public class SysLoginController extends BaseController
|
|||
}
|
||||
}
|
||||
|
||||
@ApiOperation("获取Json格式AccessToken")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class),
|
||||
@ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class),
|
||||
})
|
||||
@PostMapping("/jwt/login")
|
||||
@ResponseBody
|
||||
public AjaxResult jwtLogin(String username, String password)
|
||||
{
|
||||
return jwtTokenService.AjaxResultJwtToken(username,password);
|
||||
}
|
||||
|
||||
@ApiOperation("获取String格式AccessToken")
|
||||
@PostMapping("/jwt/topgplogin")
|
||||
@ResponseBody
|
||||
public String topgpJwtLogin(String username, String password)
|
||||
{
|
||||
return JSONObject.toJSONString(jwtTokenService.AjaxResultJwtToken(username,password));
|
||||
}
|
||||
|
||||
@GetMapping("/unauth")
|
||||
public String unauth()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -55,9 +55,9 @@ public class SwaggerConfig
|
|||
// 用ApiInfoBuilder进行定制
|
||||
return new ApiInfoBuilder()
|
||||
// 设置标题
|
||||
.title("标题:若依管理系统_接口文档")
|
||||
.title("BPS管理系统_接口文档")
|
||||
// 描述
|
||||
.description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
|
||||
.description("描述:用于管理系统的各类接口的文档说明。")
|
||||
// 作者信息
|
||||
.contact(new Contact(RuoYiConfig.getName(), null, null))
|
||||
// 版本
|
||||
|
|
|
|||
|
|
@ -77,12 +77,19 @@
|
|||
<artifactId>ruoyi-system</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--ldap-->
|
||||
<!--ldap 登录集成-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-ldap</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- jwt 集成-->
|
||||
<dependency>
|
||||
<groupId>com.auth0</groupId>
|
||||
<artifactId>java-jwt</artifactId>
|
||||
<version>3.4.0</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -25,6 +25,8 @@ import com.ruoyi.common.constant.Constants;
|
|||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.security.CipherUtils;
|
||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||
import com.ruoyi.framework.jwt.auth.AllowAllCredentialsMatcher;
|
||||
import com.ruoyi.framework.jwt.filter.JwtFilter;
|
||||
import com.ruoyi.framework.shiro.realm.UserRealm;
|
||||
import com.ruoyi.framework.shiro.session.OnlineSessionDAO;
|
||||
import com.ruoyi.framework.shiro.session.OnlineSessionFactory;
|
||||
|
|
@ -177,6 +179,7 @@ public class ShiroConfig
|
|||
UserRealm userRealm = new UserRealm();
|
||||
userRealm.setAuthorizationCacheName(Constants.SYS_AUTH_CACHE);
|
||||
userRealm.setCacheManager(cacheManager);
|
||||
userRealm.setCredentialsMatcher(new AllowAllCredentialsMatcher());
|
||||
return userRealm;
|
||||
}
|
||||
|
||||
|
|
@ -287,6 +290,8 @@ public class ShiroConfig
|
|||
filterChainDefinitionMap.put("/logout", "logout");
|
||||
// 不需要拦截的访问
|
||||
filterChainDefinitionMap.put("/login", "anon,captchaValidate");
|
||||
filterChainDefinitionMap.put("/jwt/login", "anon");
|
||||
filterChainDefinitionMap.put("/jwt/topgplogin", "anon");
|
||||
// 注册相关
|
||||
filterChainDefinitionMap.put("/register", "anon,captchaValidate");
|
||||
// 系统权限列表
|
||||
|
|
@ -297,10 +302,14 @@ public class ShiroConfig
|
|||
filters.put("syncOnlineSession", syncOnlineSessionFilter());
|
||||
filters.put("captchaValidate", captchaValidateFilter());
|
||||
filters.put("kickout", kickoutSessionFilter());
|
||||
filters.put("jwt", new JwtFilter());
|
||||
// 注销成功,则跳转到指定页面
|
||||
filters.put("logout", logoutFilter());
|
||||
shiroFilterFactoryBean.setFilters(filters);
|
||||
|
||||
// jwt 请求单独验证
|
||||
filterChainDefinitionMap.put("/api/**", "jwt");
|
||||
|
||||
// 所有请求需要认证
|
||||
filterChainDefinitionMap.put("/**", "user,kickout,onlineSession,syncOnlineSession");
|
||||
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
package com.ruoyi.framework.jwt.auth;
|
||||
|
||||
import org.apache.shiro.authc.AuthenticationInfo;
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
|
||||
|
||||
/**
|
||||
* 无需验证密码
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class AllowAllCredentialsMatcher extends SimpleCredentialsMatcher
|
||||
{
|
||||
@Override
|
||||
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package com.ruoyi.framework.jwt.auth;
|
||||
|
||||
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||
|
||||
/**
|
||||
* 自定义登录Token
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class JwtToken extends UsernamePasswordToken
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String token;
|
||||
|
||||
public JwtToken()
|
||||
{
|
||||
}
|
||||
|
||||
public JwtToken(String username, String password, boolean rememberMe)
|
||||
{
|
||||
super(username, password, rememberMe);
|
||||
}
|
||||
|
||||
public JwtToken(String username, String password)
|
||||
{
|
||||
super(username, password, false);
|
||||
}
|
||||
|
||||
public JwtToken(String token)
|
||||
{
|
||||
super("", "", false);
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public String getToken()
|
||||
{
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token)
|
||||
{
|
||||
this.token = token;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
package com.ruoyi.framework.jwt.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.web.filter.AccessControlFilter;
|
||||
import org.apache.shiro.web.util.WebUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.auth0.jwt.exceptions.JWTVerificationException;
|
||||
import com.auth0.jwt.exceptions.TokenExpiredException;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.framework.jwt.auth.JwtToken;
|
||||
|
||||
/**
|
||||
* jwt 自定义拦截器
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class JwtFilter extends AccessControlFilter
|
||||
{
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(JwtFilter.class);
|
||||
|
||||
private static final String AUTHZ_HEADER = "token";
|
||||
|
||||
private final ThreadLocal<String> MSG_HOLDER = new ThreadLocal<>();
|
||||
|
||||
@Override
|
||||
public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception
|
||||
{
|
||||
return super.onPreHandle(request, response, mappedValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception
|
||||
{
|
||||
return this.executeLogin(request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行登录方法(UserRealm判断,异常返回false)
|
||||
*/
|
||||
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception
|
||||
{
|
||||
String token = WebUtils.toHttp(request).getHeader(AUTHZ_HEADER);
|
||||
if (StringUtils.isEmpty(token))
|
||||
{
|
||||
MSG_HOLDER.set("消息头不正确,header需要携带token参数");
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
// 断是否有权限
|
||||
JwtToken jwtToken = new JwtToken(token);
|
||||
this.getSubject(request, response).login(jwtToken);
|
||||
return true;
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
if (e.getCause() instanceof TokenExpiredException)
|
||||
{
|
||||
MSG_HOLDER.set("token已过期");
|
||||
}
|
||||
else if (e.getCause() instanceof JWTVerificationException)
|
||||
{
|
||||
MSG_HOLDER.set("用户密码错误");
|
||||
}
|
||||
else
|
||||
{
|
||||
MSG_HOLDER.set("用户信息验证失败:" + e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求前处理,处理跨域
|
||||
*/
|
||||
@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请求直接返回正常状态
|
||||
if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name()))
|
||||
{
|
||||
httpServletResponse.setStatus(HttpStatus.OK.value());
|
||||
return false;
|
||||
}
|
||||
return super.preHandle(request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异常处理
|
||||
*/
|
||||
@Override
|
||||
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception
|
||||
{
|
||||
this.jwtFail(request, response, 401, "对不起,您无权限进行操作!");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 认证失败,异常返回
|
||||
*/
|
||||
protected void jwtFail(ServletRequest request, ServletResponse response, int code, String message)
|
||||
{
|
||||
HttpServletResponse httpResponse = WebUtils.toHttp(response);
|
||||
String contentType = "application/json;charset=UTF-8";
|
||||
httpResponse.setStatus(401);
|
||||
httpResponse.setContentType(contentType);
|
||||
try
|
||||
{
|
||||
String msg = StringUtils.isNotEmpty(MSG_HOLDER.get()) ? MSG_HOLDER.get() : message;
|
||||
AjaxResult ajaxResult = new AjaxResult().put(AjaxResult.CODE_TAG, code).put(AjaxResult.MSG_TAG, msg);
|
||||
PrintWriter printWriter = httpResponse.getWriter();
|
||||
printWriter.append(JSON.toJSONString(ajaxResult));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOGGER.error("sendChallenge error,can not resolve httpServletResponse");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.ruoyi.framework.jwt.service;
|
||||
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
|
||||
public interface IJwtTokenService {
|
||||
/**
|
||||
* 获取AjaxResult格式的jwt token
|
||||
* @param username 用户名
|
||||
* @param password 密码
|
||||
* @return jwtToken
|
||||
*/
|
||||
public AjaxResult AjaxResultJwtToken(String username, String password);
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package com.ruoyi.framework.jwt.service.impl;
|
||||
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.enums.UserStatus;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.framework.jwt.service.IJwtTokenService;
|
||||
import com.ruoyi.framework.jwt.utils.JwtUtils;
|
||||
import com.ruoyi.framework.shiro.service.SysPasswordService;
|
||||
import com.ruoyi.system.service.ISysUserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class JwtTokenServiceImpl implements IJwtTokenService {
|
||||
@Autowired
|
||||
private ISysUserService userService;
|
||||
|
||||
@Autowired
|
||||
private SysPasswordService passwordService;
|
||||
/**
|
||||
* 获取AjaxResult格式的jwt token
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param password 密码
|
||||
* @return jwtToken
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult AjaxResultJwtToken(String username, String password) {
|
||||
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password))
|
||||
{
|
||||
return AjaxResult.error("账号和密码不能为空!");
|
||||
}
|
||||
|
||||
SysUser user = userService.selectUserByLoginName(username);
|
||||
if (user == null)
|
||||
{
|
||||
return AjaxResult.error("用户不存在/密码错误!");
|
||||
}
|
||||
|
||||
if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
|
||||
{
|
||||
return AjaxResult.error("对不起,您的账号已被删除!");
|
||||
}
|
||||
|
||||
if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
|
||||
{
|
||||
return AjaxResult.error("用户已封禁,请联系管理员!");
|
||||
}
|
||||
|
||||
if (!passwordService.matches(user, password))
|
||||
{
|
||||
return AjaxResult.error("用户不存在/密码错误!");
|
||||
}
|
||||
|
||||
String token = JwtUtils.createToken(username, user.getPassword());
|
||||
return AjaxResult.success("登录成功,请妥善保管您的token信息").put("token", token);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
package com.ruoyi.framework.jwt.utils;
|
||||
|
||||
import java.util.Date;
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.JWTVerifier;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.exceptions.JWTDecodeException;
|
||||
import com.auth0.jwt.exceptions.JWTVerificationException;
|
||||
import com.auth0.jwt.exceptions.TokenExpiredException;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
|
||||
/**
|
||||
* jwt 工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class JwtUtils
|
||||
{
|
||||
private static final long EXPIRE_TIME = 30 * 60 * 1000;
|
||||
|
||||
private static final String CLAIM_NAME = "username";
|
||||
|
||||
public static String createToken(String username, String password)
|
||||
{
|
||||
return createToken(username, password, EXPIRE_TIME);
|
||||
}
|
||||
|
||||
public static String createToken(String username, String password, long expireTime)
|
||||
{
|
||||
Date date = new Date(System.currentTimeMillis() + expireTime);
|
||||
// 加密处理密码
|
||||
Algorithm algorithm = Algorithm.HMAC256(password);
|
||||
return JWT.create().withClaim(CLAIM_NAME, username).withExpiresAt(date).sign(algorithm);
|
||||
}
|
||||
|
||||
public static void verify(String username, String dbPwd, String token)
|
||||
{
|
||||
Algorithm algorithm = Algorithm.HMAC256(dbPwd);
|
||||
JWTVerifier jwtVerifier = JWT.require(algorithm).withClaim(CLAIM_NAME, username).build();
|
||||
try
|
||||
{
|
||||
jwtVerifier.verify(token);
|
||||
}
|
||||
catch (TokenExpiredException e)
|
||||
{
|
||||
throw new TokenExpiredException("token已过期");
|
||||
}
|
||||
catch (JWTVerificationException e)
|
||||
{
|
||||
throw new JWTVerificationException("token验证失败");
|
||||
}
|
||||
}
|
||||
|
||||
public static String getUserName(String token)
|
||||
{
|
||||
try
|
||||
{
|
||||
DecodedJWT jwt = JWT.decode(token);
|
||||
return jwt.getClaim(CLAIM_NAME).asString();
|
||||
}
|
||||
catch (JWTDecodeException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import java.util.HashSet;
|
|||
import java.util.Set;
|
||||
|
||||
import com.ruoyi.framework.shiro.util.CustToken;
|
||||
import org.apache.shiro.authc.AccountException;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.AuthenticationInfo;
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
|
|
@ -23,16 +24,21 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.enums.UserStatus;
|
||||
import com.ruoyi.common.exception.user.CaptchaException;
|
||||
import com.ruoyi.common.exception.user.RoleBlockedException;
|
||||
import com.ruoyi.common.exception.user.UserBlockedException;
|
||||
import com.ruoyi.common.exception.user.UserDeleteException;
|
||||
import com.ruoyi.common.exception.user.UserNotExistsException;
|
||||
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
|
||||
import com.ruoyi.common.exception.user.UserPasswordRetryLimitExceedException;
|
||||
import com.ruoyi.common.utils.ShiroUtils;
|
||||
import com.ruoyi.framework.jwt.auth.JwtToken;
|
||||
import com.ruoyi.framework.jwt.utils.JwtUtils;
|
||||
import com.ruoyi.framework.shiro.service.SysLoginService;
|
||||
import com.ruoyi.system.service.ISysMenuService;
|
||||
import com.ruoyi.system.service.ISysRoleService;
|
||||
import com.ruoyi.system.service.ISysUserService;
|
||||
|
||||
/**
|
||||
* 自定义Realm 处理登录 权限
|
||||
|
|
@ -52,6 +58,9 @@ public class UserRealm extends AuthorizingRealm
|
|||
@Autowired
|
||||
private SysLoginService loginService;
|
||||
|
||||
@Autowired
|
||||
private ISysUserService userService;
|
||||
|
||||
/**
|
||||
* 授权
|
||||
*/
|
||||
|
|
@ -86,55 +95,96 @@ public class UserRealm extends AuthorizingRealm
|
|||
* 登录认证
|
||||
*/
|
||||
@Override
|
||||
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
|
||||
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
|
||||
throws AuthenticationException
|
||||
{
|
||||
//UsernamePasswordToken upToken = (UsernamePasswordToken) token;
|
||||
CustToken upToken= (CustToken) token;
|
||||
String loginType = upToken.getLoginType();
|
||||
String username = upToken.getUsername();
|
||||
String password = "";
|
||||
if (authenticationToken instanceof JwtToken)
|
||||
{
|
||||
JwtToken jwtToken = (JwtToken) authenticationToken;
|
||||
String token = jwtToken.getToken();
|
||||
String username = JwtUtils.getUserName(token);
|
||||
if (username == null)
|
||||
{
|
||||
throw new AccountException("token 验证失败");
|
||||
}
|
||||
SysUser user = userService.selectUserByLoginName(username);
|
||||
if (user == null)
|
||||
{
|
||||
throw new AuthenticationException("用户数据不存在");
|
||||
}
|
||||
|
||||
if (upToken.getPassword() != null)
|
||||
{
|
||||
password = new String(upToken.getPassword());
|
||||
}
|
||||
try
|
||||
{
|
||||
JwtUtils.verify(username, user.getPassword(), jwtToken.getToken());
|
||||
|
||||
SysUser user = null;
|
||||
try
|
||||
{
|
||||
user = loginService.login(username, password,loginType);
|
||||
if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
|
||||
{
|
||||
throw new UserDeleteException();
|
||||
}
|
||||
|
||||
if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
|
||||
{
|
||||
throw new UserBlockedException();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.info("对用户[" + username + "]进行jwt登录验证..验证未通过{}", e.getMessage());
|
||||
throw new AuthenticationException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
return new SimpleAuthenticationInfo(user, null, getName());
|
||||
}
|
||||
catch (CaptchaException e)
|
||||
else
|
||||
{
|
||||
throw new AuthenticationException(e.getMessage(), e);
|
||||
//UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;
|
||||
CustToken upToken= (CustToken) authenticationToken;
|
||||
String loginType = upToken.getLoginType();
|
||||
String username = upToken.getUsername();
|
||||
String password = "";
|
||||
|
||||
if (upToken.getPassword() != null)
|
||||
{
|
||||
password = new String(upToken.getPassword());
|
||||
}
|
||||
|
||||
SysUser user = null;
|
||||
try
|
||||
{
|
||||
user = loginService.login(username, password,loginType);
|
||||
}
|
||||
catch (CaptchaException e)
|
||||
{
|
||||
throw new AuthenticationException(e.getMessage(), e);
|
||||
}
|
||||
catch (UserNotExistsException e)
|
||||
{
|
||||
throw new UnknownAccountException(e.getMessage(), e);
|
||||
}
|
||||
catch (UserPasswordNotMatchException e)
|
||||
{
|
||||
throw new IncorrectCredentialsException(e.getMessage(), e);
|
||||
}
|
||||
catch (UserPasswordRetryLimitExceedException e)
|
||||
{
|
||||
throw new ExcessiveAttemptsException(e.getMessage(), e);
|
||||
}
|
||||
catch (UserBlockedException e)
|
||||
{
|
||||
throw new LockedAccountException(e.getMessage(), e);
|
||||
}
|
||||
catch (RoleBlockedException e)
|
||||
{
|
||||
throw new LockedAccountException(e.getMessage(), e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.info("对用户[" + username + "]进行登录验证..验证未通过{}", e.getMessage());
|
||||
throw new AuthenticationException(e.getMessage(), e);
|
||||
}
|
||||
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
|
||||
return info;
|
||||
}
|
||||
catch (UserNotExistsException e)
|
||||
{
|
||||
throw new UnknownAccountException(e.getMessage(), e);
|
||||
}
|
||||
catch (UserPasswordNotMatchException e)
|
||||
{
|
||||
throw new IncorrectCredentialsException(e.getMessage(), e);
|
||||
}
|
||||
catch (UserPasswordRetryLimitExceedException e)
|
||||
{
|
||||
throw new ExcessiveAttemptsException(e.getMessage(), e);
|
||||
}
|
||||
catch (UserBlockedException e)
|
||||
{
|
||||
throw new LockedAccountException(e.getMessage(), e);
|
||||
}
|
||||
catch (RoleBlockedException e)
|
||||
{
|
||||
throw new LockedAccountException(e.getMessage(), e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.info("对用户[" + username + "]进行登录验证..验证未通过{}", e.getMessage());
|
||||
throw new AuthenticationException(e.getMessage(), e);
|
||||
}
|
||||
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import com.ruoyi.common.core.domain.AjaxResult;
|
|||
import com.ruoyi.common.exception.BusinessException;
|
||||
import com.ruoyi.common.exception.DemoModeException;
|
||||
import com.ruoyi.common.utils.ServletUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.security.PermissionUtils;
|
||||
|
||||
/**
|
||||
|
|
@ -32,7 +33,7 @@ public class GlobalExceptionHandler
|
|||
public Object handleAuthorizationException(HttpServletRequest request, AuthorizationException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
if (ServletUtils.isAjaxRequest(request))
|
||||
if (ServletUtils.isAjaxRequest(request) || StringUtils.isNotEmpty(request.getHeader("token")))
|
||||
{
|
||||
return AjaxResult.error(PermissionUtils.getMsg(e.getMessage()));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue