| @@ -0,0 +1,25 @@ | |||||
| package com.ruoyi.auth.config; | |||||
| import lombok.Getter; | |||||
| import lombok.Setter; | |||||
| import org.springframework.boot.context.properties.ConfigurationProperties; | |||||
| import org.springframework.cloud.context.config.annotation.RefreshScope; | |||||
| import org.springframework.context.annotation.Configuration; | |||||
| @Configuration | |||||
| @RefreshScope | |||||
| @ConfigurationProperties(prefix = "oauth2") | |||||
| @Getter | |||||
| @Setter | |||||
| public class Oauth2ClientProperties { | |||||
| private String clientId; | |||||
| private String clientSecret; | |||||
| private String scope; | |||||
| private String userAuthorizationUri; | |||||
| private String accessTokenUri; | |||||
| private String redirectUri; | |||||
| private String logoutUri; | |||||
| private String checkTokenUri; | |||||
| private String loginPage; | |||||
| } | |||||
| @@ -2,12 +2,19 @@ package com.ruoyi.auth.controller; | |||||
| import javax.servlet.http.HttpServletRequest; | import javax.servlet.http.HttpServletRequest; | ||||
| import com.alibaba.fastjson2.JSON; | |||||
| import com.ruoyi.auth.config.Oauth2ClientProperties; | |||||
| import com.ruoyi.auth.form.AccessTokenVo; | |||||
| import com.ruoyi.auth.form.LoginKeyBody; | import com.ruoyi.auth.form.LoginKeyBody; | ||||
| import com.ruoyi.common.core.exception.ServiceException; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.web.bind.annotation.DeleteMapping; | |||||
| import org.springframework.web.bind.annotation.PostMapping; | |||||
| import org.springframework.web.bind.annotation.RequestBody; | |||||
| import org.springframework.web.bind.annotation.RestController; | |||||
| import org.springframework.http.HttpEntity; | |||||
| import org.springframework.http.HttpHeaders; | |||||
| import org.springframework.http.MediaType; | |||||
| import org.springframework.http.ResponseEntity; | |||||
| import org.springframework.util.LinkedMultiValueMap; | |||||
| import org.springframework.util.MultiValueMap; | |||||
| import org.springframework.web.bind.annotation.*; | |||||
| import com.ruoyi.auth.form.LoginBody; | import com.ruoyi.auth.form.LoginBody; | ||||
| import com.ruoyi.auth.form.RegisterBody; | import com.ruoyi.auth.form.RegisterBody; | ||||
| import com.ruoyi.auth.service.SysLoginService; | import com.ruoyi.auth.service.SysLoginService; | ||||
| @@ -18,6 +25,9 @@ import com.ruoyi.common.security.auth.AuthUtil; | |||||
| import com.ruoyi.common.security.service.TokenService; | import com.ruoyi.common.security.service.TokenService; | ||||
| import com.ruoyi.common.security.utils.SecurityUtils; | import com.ruoyi.common.security.utils.SecurityUtils; | ||||
| import com.ruoyi.system.api.model.LoginUser; | import com.ruoyi.system.api.model.LoginUser; | ||||
| import org.springframework.web.client.RestTemplate; | |||||
| import java.util.Map; | |||||
| /** | /** | ||||
| * token 控制 | * token 控制 | ||||
| @@ -33,6 +43,9 @@ public class TokenController | |||||
| @Autowired | @Autowired | ||||
| private SysLoginService sysLoginService; | private SysLoginService sysLoginService; | ||||
| @Autowired | |||||
| private Oauth2ClientProperties oauth2ClientProperties; | |||||
| @PostMapping("login") | @PostMapping("login") | ||||
| public R<?> login(@RequestBody LoginBody form) | public R<?> login(@RequestBody LoginBody form) | ||||
| { | { | ||||
| @@ -51,6 +64,64 @@ public class TokenController | |||||
| return R.ok(tokenService.createToken(userInfo)); | return R.ok(tokenService.createToken(userInfo)); | ||||
| } | } | ||||
| @PostMapping("loginByOauth2") | |||||
| public R<?> loginByOauth2(@RequestBody Map<String,String> params) | |||||
| /** | |||||
| * { | |||||
| * "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiZGVtby1hcHAiXSwiZXhwIjoxNzI5MTU0MTExLCJ1c2VyX25hbWUiOiJhZG1pbiIsImp0aSI6IjQzNGVkNmI0LWIzN2MtNDliMS04NTczLWZhNmU4YTg5YTUxYSIsImNsaWVudF9pZCI6IkFCQyIsInNjb3BlIjpbInJlYWQiLCJ3cml0ZSJdfQ.U591q4fUaUBtBt5Ex-S2daM7DIl9-Ov0MsveymNfHxI", | |||||
| * "token_type": "bearer", | |||||
| * "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiZGVtby1hcHAiXSwidXNlcl9uYW1lIjoiYWRtaW4iLCJzY29wZSI6WyJyZWFkIiwid3JpdGUiXSwiYXRpIjoiNDM0ZWQ2YjQtYjM3Yy00OWIxLTg1NzMtZmE2ZThhODlhNTFhIiwiZXhwIjoxNzMxNjQ5OTY4LCJqdGkiOiJiODFhNmJkMC02ZDQzLTQ4M2QtOThmMy1hZWIxNDcyZDUwNzciLCJjbGllbnRfaWQiOiJBQkMifQ.0uMYVqW1G7j0chwxIdWGwpjDr12ogZPcD1iQfPsAs5k", | |||||
| * "expires_in": 7198, | |||||
| * "scope": "read write", | |||||
| * "account_info": { | |||||
| * "id": 1, | |||||
| * "clientId": "ABC", | |||||
| * "username": "admin", | |||||
| * "mobile": "1232378743", | |||||
| * "email": "abc@123.com" | |||||
| * } | |||||
| * } | |||||
| */ | |||||
| { | |||||
| if (params.containsKey("code") && StringUtils.isNotBlank(params.get("code"))){ | |||||
| RestTemplate restTemplate = new RestTemplate(); | |||||
| String url = oauth2ClientProperties.getAccessTokenUri(); | |||||
| HttpHeaders headers = new HttpHeaders(); | |||||
| headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); | |||||
| MultiValueMap<String, String> map= new LinkedMultiValueMap<>(); | |||||
| map.add("grant_type", "authorization_code"); | |||||
| map.add("code", params.get("code")); | |||||
| map.add("redirect_uri", oauth2ClientProperties.getRedirectUri()); | |||||
| map.add("client_id", oauth2ClientProperties.getClientId()); | |||||
| map.add("client_secret", oauth2ClientProperties.getClientSecret()); | |||||
| HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers); | |||||
| ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class); | |||||
| String body = response.getBody(); | |||||
| AccessTokenVo accessTokenVo = JSON.parseObject(body, AccessTokenVo.class); | |||||
| String accessToken = accessTokenVo.getAccess_token(); | |||||
| AccessTokenVo.Account_info accountInfo = accessTokenVo.getAccount_info(); | |||||
| // 用户登录 | |||||
| LoginUser userInfo = sysLoginService.login(accountInfo); | |||||
| // 获取登录token | |||||
| Map<String, Object> token = tokenService.createToken(userInfo); | |||||
| token.put("checkTokenUri",oauth2ClientProperties.getCheckTokenUri()); | |||||
| token.put("logoutUri",oauth2ClientProperties.getLogoutUri()); | |||||
| token.put("oauth2AccessToken",accessToken); | |||||
| return R.ok(token); | |||||
| } | |||||
| throw new ServiceException("用户信息获取失败"); | |||||
| } | |||||
| @GetMapping("oauth2ClientInfo") | |||||
| public R<?> getClientInfo() { | |||||
| return R.ok(JSON.toJSON(oauth2ClientProperties)); | |||||
| } | |||||
| @DeleteMapping("logout") | @DeleteMapping("logout") | ||||
| public R<?> logout(HttpServletRequest request) | public R<?> logout(HttpServletRequest request) | ||||
| { | { | ||||
| @@ -0,0 +1,119 @@ | |||||
| package com.ruoyi.auth.form; | |||||
| import java.io.Serializable; | |||||
| import java.lang.Integer; | |||||
| import java.lang.String; | |||||
| public class AccessTokenVo implements Serializable { | |||||
| private String access_token; | |||||
| private String refresh_token; | |||||
| private String scope; | |||||
| private Account_info account_info; | |||||
| private String token_type; | |||||
| private Integer expires_in; | |||||
| public String getAccess_token() { | |||||
| return this.access_token; | |||||
| } | |||||
| public void setAccess_token(String access_token) { | |||||
| this.access_token = access_token; | |||||
| } | |||||
| public String getRefresh_token() { | |||||
| return this.refresh_token; | |||||
| } | |||||
| public void setRefresh_token(String refresh_token) { | |||||
| this.refresh_token = refresh_token; | |||||
| } | |||||
| public String getScope() { | |||||
| return this.scope; | |||||
| } | |||||
| public void setScope(String scope) { | |||||
| this.scope = scope; | |||||
| } | |||||
| public Account_info getAccount_info() { | |||||
| return this.account_info; | |||||
| } | |||||
| public void setAccount_info(Account_info account_info) { | |||||
| this.account_info = account_info; | |||||
| } | |||||
| public String getToken_type() { | |||||
| return this.token_type; | |||||
| } | |||||
| public void setToken_type(String token_type) { | |||||
| this.token_type = token_type; | |||||
| } | |||||
| public Integer getExpires_in() { | |||||
| return this.expires_in; | |||||
| } | |||||
| public void setExpires_in(Integer expires_in) { | |||||
| this.expires_in = expires_in; | |||||
| } | |||||
| public static class Account_info implements Serializable { | |||||
| private String clientId; | |||||
| private String mobile; | |||||
| private Integer id; | |||||
| private String email; | |||||
| private String username; | |||||
| public String getClientId() { | |||||
| return this.clientId; | |||||
| } | |||||
| public void setClientId(String clientId) { | |||||
| this.clientId = clientId; | |||||
| } | |||||
| public String getMobile() { | |||||
| return this.mobile; | |||||
| } | |||||
| public void setMobile(String mobile) { | |||||
| this.mobile = mobile; | |||||
| } | |||||
| public Integer getId() { | |||||
| return this.id; | |||||
| } | |||||
| public void setId(Integer id) { | |||||
| this.id = id; | |||||
| } | |||||
| public String getEmail() { | |||||
| return this.email; | |||||
| } | |||||
| public void setEmail(String email) { | |||||
| this.email = email; | |||||
| } | |||||
| public String getUsername() { | |||||
| return this.username; | |||||
| } | |||||
| public void setUsername(String username) { | |||||
| this.username = username; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,5 +1,6 @@ | |||||
| package com.ruoyi.auth.service; | package com.ruoyi.auth.service; | ||||
| import com.ruoyi.auth.form.AccessTokenVo; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
| import com.ruoyi.common.core.constant.CacheConstants; | import com.ruoyi.common.core.constant.CacheConstants; | ||||
| @@ -193,4 +194,62 @@ public class SysLoginService | |||||
| } | } | ||||
| return userInfo; | return userInfo; | ||||
| } | } | ||||
| public LoginUser login(AccessTokenVo.Account_info accountInfo) { | |||||
| String username = accountInfo.getUsername(); | |||||
| // 用户名或密码为空 错误 | |||||
| if (StringUtils.isAnyBlank(username)) | |||||
| { | |||||
| recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户/密码必须填写"); | |||||
| throw new ServiceException("用户/密码必须填写"); | |||||
| } | |||||
| // 用户名不在指定范围内 错误 | |||||
| if (username.length() < UserConstants.USERNAME_MIN_LENGTH | |||||
| || username.length() > UserConstants.USERNAME_MAX_LENGTH) | |||||
| { | |||||
| recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户名不在指定范围"); | |||||
| throw new ServiceException("用户名不在指定范围"); | |||||
| } | |||||
| // IP黑名单校验 | |||||
| String blackStr = Convert.toStr(redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST)); | |||||
| if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) | |||||
| { | |||||
| recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "很遗憾,访问IP已被列入系统黑名单"); | |||||
| throw new ServiceException("很遗憾,访问IP已被列入系统黑名单"); | |||||
| } | |||||
| // 查询用户信息 | |||||
| R<LoginUser> userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER); | |||||
| if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData())) | |||||
| { | |||||
| recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "登录用户不存在"); | |||||
| throw new ServiceException("登录用户:" + username + " 不存在"); | |||||
| // register(username, "123456"); | |||||
| // userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER); | |||||
| } | |||||
| if (R.FAIL == userResult.getCode()) | |||||
| { | |||||
| throw new ServiceException(userResult.getMsg()); | |||||
| } | |||||
| LoginUser userInfo = userResult.getData(); | |||||
| SysUser user = userResult.getData().getSysUser(); | |||||
| if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) | |||||
| { | |||||
| recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除"); | |||||
| throw new ServiceException("对不起,您的账号:" + username + " 已被删除"); | |||||
| } | |||||
| if (UserStatus.DISABLE.getCode().equals(user.getStatus())) | |||||
| { | |||||
| recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员"); | |||||
| throw new ServiceException("对不起,您的账号:" + username + " 已停用"); | |||||
| } | |||||
| recordLogService.recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功"); | |||||
| return userInfo; | |||||
| } | |||||
| } | } | ||||
| @@ -13,17 +13,19 @@ spring: | |||||
| cloud: | cloud: | ||||
| nacos: | nacos: | ||||
| discovery: | discovery: | ||||
| namespace: cc149503-5508-4da9-a735-9505e2a91363 | |||||
| # 服务注册地址 | # 服务注册地址 | ||||
| server-addr: nacos-ci4s.argo.svc:8848 | |||||
| server-addr: 172.20.32.181:31203 | |||||
| username: nacos | username: nacos | ||||
| password: h1n2x3j4y5@ | password: h1n2x3j4y5@ | ||||
| retry: | retry: | ||||
| enabled: true | enabled: true | ||||
| config: | config: | ||||
| namespace: cc149503-5508-4da9-a735-9505e2a91363 | |||||
| username: nacos | username: nacos | ||||
| password: h1n2x3j4y5@ | password: h1n2x3j4y5@ | ||||
| # 配置中心地址 | # 配置中心地址 | ||||
| server-addr: nacos-ci4s.argo.svc:8848 | |||||
| server-addr: 172.20.32.181:31203 | |||||
| # 配置文件格式 | # 配置文件格式 | ||||
| file-extension: yml | file-extension: yml | ||||
| # 共享配置 | # 共享配置 | ||||
| @@ -36,6 +38,18 @@ spring: | |||||
| refresh: true | refresh: true | ||||
| redis: | redis: | ||||
| host: 172.20.32.150 | |||||
| host: 172.20.32.88 | |||||
| port: 6379 | port: 6379 | ||||
| password: | |||||
| password: | |||||
| oauth2: | |||||
| url: http://172.20.32.106:8080 | |||||
| # url: http://110.41.62.43:8088 | |||||
| client-id: ci4s | |||||
| client-secret: 123456 | |||||
| user-authorization-uri: ${oauth2.url}/oauth/authorize | |||||
| access-token-uri: ${oauth2.url}/oauth/token | |||||
| logout-uri: ${oauth2.url}/logout | |||||
| redirect-uri: http://172.20.32.83:8002/authorize | |||||
| check-token-uri: ${oauth2.url}/oauth/check_token | |||||
| login-page: ${oauth2.url}/login.html | |||||
| @@ -3,7 +3,11 @@ server: | |||||
| port: 8082 | port: 8082 | ||||
| # Spring | # Spring | ||||
| spring: | |||||
| spring: | |||||
| redis: | |||||
| host: 172.20.32.88 | |||||
| port: 6379 | |||||
| password: | |||||
| application: | application: | ||||
| # 应用名称 | # 应用名称 | ||||
| name: ruoyi-gateway | name: ruoyi-gateway | ||||
| @@ -14,16 +18,18 @@ spring: | |||||
| nacos: | nacos: | ||||
| discovery: | discovery: | ||||
| # 服务注册地址 | # 服务注册地址 | ||||
| server-addr: nacos-ci4s.argo.svc:8848 | |||||
| server-addr: 172.20.32.181:31203 | |||||
| username: nacos | username: nacos | ||||
| password: h1n2x3j4y5@ | password: h1n2x3j4y5@ | ||||
| retry: | retry: | ||||
| enabled: true | enabled: true | ||||
| namespace: cc149503-5508-4da9-a735-9505e2a91363 | |||||
| config: | config: | ||||
| namespace: cc149503-5508-4da9-a735-9505e2a91363 | |||||
| username: nacos | username: nacos | ||||
| password: h1n2x3j4y5@ | password: h1n2x3j4y5@ | ||||
| # 配置中心地址 | # 配置中心地址 | ||||
| server-addr: nacos-ci4s.argo.svc:8848 | |||||
| server-addr: 172.20.32.181:31203 | |||||
| # 配置文件格式 | # 配置文件格式 | ||||
| file-extension: yml | file-extension: yml | ||||
| # 共享配置 | # 共享配置 | ||||
| @@ -14,14 +14,16 @@ spring: | |||||
| nacos: | nacos: | ||||
| discovery: | discovery: | ||||
| # 服务注册地址 | # 服务注册地址 | ||||
| server-addr: nacos-ci4s.argo.svc:8848 | |||||
| namespace: cc149503-5508-4da9-a735-9505e2a91363 | |||||
| server-addr: 172.20.32.181:31203 | |||||
| username: nacos | username: nacos | ||||
| password: h1n2x3j4y5@ | password: h1n2x3j4y5@ | ||||
| config: | config: | ||||
| namespace: cc149503-5508-4da9-a735-9505e2a91363 | |||||
| username: nacos | username: nacos | ||||
| password: h1n2x3j4y5@ | password: h1n2x3j4y5@ | ||||
| # 配置中心地址 | # 配置中心地址 | ||||
| server-addr: nacos-ci4s.argo.svc:8848 | |||||
| server-addr: 172.20.32.181:31203 | |||||
| # 配置文件格式 | # 配置文件格式 | ||||
| file-extension: yml | file-extension: yml | ||||
| # 共享配置 | # 共享配置 | ||||