认证和权限相关内容调整

V0.5.x
xiwa 2022-05-21 15:35:48 +08:00
parent 26049a96fd
commit 68bae76a8c
28 changed files with 232 additions and 246 deletions

View File

@ -1,6 +1,7 @@
package cc.iotkit.common.utils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Cipher;
@ -96,4 +97,9 @@ public class CodecUtil {
encryptStr = new String(HexUtil.parseHex(encryptStr));
return StringUtils.isEmpty(encryptStr) ? "" : aesDecryptByBytes(base64Decode(encryptStr), decryptKey);
}
public static String md5Str(String content) {
return DigestUtils.md5Hex(content);
}
}

View File

@ -1,22 +0,0 @@
package cc.iotkit.manager.config;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.KeycloakDeploymentBuilder;
import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
import org.keycloak.representations.adapters.config.AdapterConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AutoBeanConfig {
@Bean
public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Bean
public KeycloakDeployment getKeycloakDeployment(AdapterConfig adapterConfig){
return KeycloakDeploymentBuilder.build(adapterConfig);
}
}

View File

@ -1,92 +0,0 @@
package cc.iotkit.manager.config;
import org.keycloak.adapters.springsecurity.KeycloakConfiguration;
import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider;
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.keycloak.adapters.springsecurity.management.HttpSessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
@EnableGlobalMethodSecurity(prePostEnabled = true)
@KeycloakConfiguration
public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Value("${app.systemRole}")
private String systemRole;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
SimpleAuthorityMapper grantedAuthorityMapper = new SimpleAuthorityMapper();
grantedAuthorityMapper.setPrefix("ROLE_");
KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(grantedAuthorityMapper);
auth.authenticationProvider(keycloakAuthenticationProvider);
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
// return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
return new NullAuthenticatedSessionStrategy();
}
@Bean
@Override
@ConditionalOnMissingBean(HttpSessionManager.class)
protected HttpSessionManager httpSessionManager() {
return new HttpSessionManager();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http
.authorizeRequests()
.antMatchers("/*.html", "/favicon.ico", "/v2/api-docs", "/webjars/**", "/swagger-resources/**", "/*.js").permitAll()
.antMatchers("/api/**").hasRole("iot_client_user")
.antMatchers("/aligenieDevice/invoke/**").hasRole("iot_client_user")
//客户端用户写权限
.antMatchers("/space/addSpace/**").hasAnyRole("iot_write","iot_client_user")
.antMatchers("/space/saveSpace/**").hasAnyRole("iot_write","iot_client_user")
.antMatchers("/space/delSpace/**").hasAnyRole("iot_write","iot_client_user")
.antMatchers("/space/saveHome/**").hasAnyRole("iot_write","iot_client_user")
.antMatchers("/space/currentHome/**").hasAnyRole("iot_write","iot_client_user")
.antMatchers("/space/myRecentDevices/**").hasAnyRole("iot_write","iot_client_user")
.antMatchers("/space/spaces/**").hasAnyRole("iot_write","iot_client_user")
.antMatchers("/space/myDevices/**").hasAnyRole("iot_write","iot_client_user")
.antMatchers("/space/findDevice/**").hasAnyRole("iot_write","iot_client_user")
.antMatchers("/space/addDevice/**").hasAnyRole("iot_write","iot_client_user")
.antMatchers("/space/saveDevice").hasAnyRole("iot_write","iot_client_user")
.antMatchers("/space/removeDevice").hasAnyRole("iot_write","iot_client_user")
.antMatchers("/space/device/*").hasAnyRole("iot_write","iot_client_user")
.antMatchers("/device/*/consumer/*").hasAnyRole("iot_write","iot_client_user")
.antMatchers("/device/*/service/property/set").hasAnyRole("iot_write","iot_client_user")
.antMatchers("/device/*/service/*/invoke").hasAnyRole("iot_write","iot_client_user")
.antMatchers(HttpMethod.DELETE).hasRole("iot_write")
.antMatchers(HttpMethod.PUT).hasRole("iot_write")
.antMatchers("/**/save*/**").hasRole("iot_write")
.antMatchers("/**/remove*/**").hasRole("iot_write")
.antMatchers("/**/del*/**").hasRole("iot_write")
.antMatchers("/**/add*/**").hasRole("iot_write")
.antMatchers("/**/clear*/**").hasRole("iot_write")
.antMatchers("/**/set*/**").hasRole("iot_write")
.antMatchers("/**/set").hasRole("iot_write")
.antMatchers("/**/invoke").hasRole("iot_write")
.antMatchers("/**").hasAnyRole(systemRole)
.and().csrf().disable();
}
}

View File

@ -4,10 +4,12 @@ import cn.dev33.satoken.interceptor.SaAnnotationInterceptor;
import cn.dev33.satoken.interceptor.SaRouteInterceptor;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Slf4j
@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
@ -17,23 +19,8 @@ public class SaTokenConfigure implements WebMvcConfigurer {
registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
// 注册路由拦截器,自定义认证规则
registry.addInterceptor(new SaRouteInterceptor((req, res, handler) -> {
System.out.println(req.getRequestPath());
// 根据路由划分模块,不同模块不同鉴权
log.info("resource role check,path:{}", req.getRequestPath());
SaRouter
//管理员、系统用户角色能使用的功能
.match("/**")
.notMatch("/oauth2/**","/*.png").check(c -> StpUtil.checkRoleOr("iot_admin", "iot_system"))
//需要有可写权限的功能
.match(
"/**/save*/**",
"/**/remove*/**",
"/**/del*/**",
"/**/add*/**",
"/**/clear*/**",
"/**/set*/**",
"/**/set",
"/**/invoke"
).check(c -> StpUtil.checkPermission("write"))
//管理员、系统、客户端用户角色能使用的功能
.match("/space/addSpace/**",
"/space/saveSpace/**",
@ -52,7 +39,26 @@ public class SaTokenConfigure implements WebMvcConfigurer {
"/device/*/service/property/set",
"/device/*/service/*/invoke"
)
.check(c -> StpUtil.checkRoleOr("iot_admin", "iot_system", "iot_client"));
SaRouter
//需要有可写权限的功能
.match(
"/**/save*/**",
"/**/remove*/**",
"/**/del*/**",
"/**/add*/**",
"/**/clear*/**",
"/**/set*/**",
"/**/set",
"/**/invoke"
).check(c -> StpUtil.checkPermission("write"));
SaRouter
//管理员、系统用户角色能使用的功能
.match("/**")
.check(c -> StpUtil.checkRoleOr("iot_admin", "iot_system", "iot_client"))
;
})).addPathPatterns("/**")
.excludePathPatterns(

View File

@ -1,55 +0,0 @@
package cc.iotkit.manager.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${app.systemRole}")
private String systemRole;
@Override
protected void configure(HttpSecurity http) throws Exception {
// super.configure(http);
http
.authorizeRequests()
.antMatchers("/oauth2/**", "/*.html", "/favicon.ico", "/v2/api-docs", "/webjars/**", "/swagger-resources/**", "/*.js").permitAll()
.antMatchers("/api/**").hasRole("iot_client_user")
.antMatchers("/aligenieDevice/invoke/**").hasRole("iot_client_user")
//客户端用户写权限
.antMatchers("/space/addSpace/**").hasAnyRole("iot_write", "iot_client_user")
.antMatchers("/space/saveSpace/**").hasAnyRole("iot_write", "iot_client_user")
.antMatchers("/space/delSpace/**").hasAnyRole("iot_write", "iot_client_user")
.antMatchers("/space/saveHome/**").hasAnyRole("iot_write", "iot_client_user")
.antMatchers("/space/currentHome/**").hasAnyRole("iot_write", "iot_client_user")
.antMatchers("/space/myRecentDevices/**").hasAnyRole("iot_write", "iot_client_user")
.antMatchers("/space/spaces/**").hasAnyRole("iot_write", "iot_client_user")
.antMatchers("/space/myDevices/**").hasAnyRole("iot_write", "iot_client_user")
.antMatchers("/space/findDevice/**").hasAnyRole("iot_write", "iot_client_user")
.antMatchers("/space/addDevice/**").hasAnyRole("iot_write", "iot_client_user")
.antMatchers("/space/saveDevice").hasAnyRole("iot_write", "iot_client_user")
.antMatchers("/space/removeDevice").hasAnyRole("iot_write", "iot_client_user")
.antMatchers("/space/device/*").hasAnyRole("iot_write", "iot_client_user")
.antMatchers("/device/*/consumer/*").hasAnyRole("iot_write", "iot_client_user")
.antMatchers("/device/*/service/property/set").hasAnyRole("iot_write", "iot_client_user")
.antMatchers("/device/*/service/*/invoke").hasAnyRole("iot_write", "iot_client_user")
.antMatchers(HttpMethod.DELETE).hasRole("iot_write")
.antMatchers(HttpMethod.PUT).hasRole("iot_write")
.antMatchers("/**/save*/**").hasRole("iot_write")
.antMatchers("/**/remove*/**").hasRole("iot_write")
.antMatchers("/**/del*/**").hasRole("iot_write")
.antMatchers("/**/add*/**").hasRole("iot_write")
.antMatchers("/**/clear*/**").hasRole("iot_write")
.antMatchers("/**/set*/**").hasRole("iot_write")
.antMatchers("/**/set").hasRole("iot_write")
.antMatchers("/**/invoke").hasRole("iot_write")
.antMatchers("/**").hasAnyRole(systemRole)
.and().csrf().disable();
}
}

View File

@ -10,7 +10,7 @@ import cc.iotkit.manager.model.query.DeviceQuery;
import cc.iotkit.manager.service.DataOwnerService;
import cc.iotkit.manager.service.DeferredDataConsumer;
import cc.iotkit.manager.service.DeviceService;
import cc.iotkit.manager.utils.AuthUtil;
import cc.iotkit.utils.AuthUtil;
import cc.iotkit.model.InvokeResult;
import cc.iotkit.model.Paging;
import cc.iotkit.model.device.DeviceInfo;

View File

@ -9,7 +9,7 @@ import cc.iotkit.dao.ProtocolComponentRepository;
import cc.iotkit.dao.ProtocolConverterRepository;
import cc.iotkit.dao.UserInfoRepository;
import cc.iotkit.manager.service.DataOwnerService;
import cc.iotkit.manager.utils.AuthUtil;
import cc.iotkit.utils.AuthUtil;
import cc.iotkit.model.Paging;
import cc.iotkit.model.protocol.ProtocolComponent;
import cc.iotkit.model.protocol.ProtocolConverter;

View File

@ -4,7 +4,7 @@ import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.utils.ReflectUtil;
import cc.iotkit.dao.*;
import cc.iotkit.manager.service.DataOwnerService;
import cc.iotkit.manager.utils.AuthUtil;
import cc.iotkit.utils.AuthUtil;
import cc.iotkit.model.Paging;
import cc.iotkit.model.rule.RuleInfo;
import cc.iotkit.model.rule.RuleLog;

View File

@ -4,7 +4,7 @@ import cc.iotkit.common.exception.BizException;
import cc.iotkit.dao.HomeRepository;
import cc.iotkit.dao.SpaceRepository;
import cc.iotkit.manager.service.DataOwnerService;
import cc.iotkit.manager.utils.AuthUtil;
import cc.iotkit.utils.AuthUtil;
import cc.iotkit.model.space.Home;
import cc.iotkit.model.space.Space;
import org.apache.commons.lang3.StringUtils;

View File

@ -6,7 +6,7 @@ import cc.iotkit.dao.*;
import cc.iotkit.manager.model.vo.FindDeviceVo;
import cc.iotkit.manager.model.vo.SpaceDeviceVo;
import cc.iotkit.manager.service.DataOwnerService;
import cc.iotkit.manager.utils.AuthUtil;
import cc.iotkit.utils.AuthUtil;
import cc.iotkit.model.UserInfo;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.product.Category;

View File

@ -8,7 +8,7 @@ import cc.iotkit.dao.AligenieDeviceRepository;
import cc.iotkit.dao.UserInfoRepository;
import cc.iotkit.manager.service.DataOwnerService;
import cc.iotkit.manager.service.PulsarAdminService;
import cc.iotkit.manager.utils.AuthUtil;
import cc.iotkit.utils.AuthUtil;
import cc.iotkit.model.UserInfo;
import cn.dev33.satoken.annotation.SaCheckRole;
import org.springframework.beans.factory.annotation.Autowired;
@ -51,7 +51,7 @@ public class UserInfoController {
user.setRoles(Collections.singletonList(Constants.ROLE_SYSTEM));
user.setPermissions(Collections.singletonList(Constants.PERMISSION_WRITE));
user.setCreateAt(System.currentTimeMillis());
user.setSecret(CodecUtil.aesEncrypt(Constants.PWD_SYSTEM_USER, Constants.PWD_SYSTEM_USER));
user.setSecret(AuthUtil.enCryptPwd(Constants.PWD_SYSTEM_USER));
userInfoRepository.save(user);
} catch (Throwable e) {
throw new BizException("add platform user error", e);
@ -75,7 +75,7 @@ public class UserInfoController {
user.setOwnerId(AuthUtil.getUserId());
user.setRoles(Collections.singletonList(Constants.ROLE_CLIENT));
user.setCreateAt(System.currentTimeMillis());
user.setSecret(CodecUtil.aesEncrypt(Constants.PWD_CLIENT_USER, Constants.ACCOUNT_SECRET));
user.setSecret(AuthUtil.enCryptPwd(Constants.PWD_CLIENT_USER));
userInfoRepository.save(user);
}

View File

@ -2,7 +2,7 @@ package cc.iotkit.manager.controller.aligenie;
import cc.iotkit.dao.AligenieProductRepository;
import cc.iotkit.manager.service.DataOwnerService;
import cc.iotkit.manager.utils.AuthUtil;
import cc.iotkit.utils.AuthUtil;
import cc.iotkit.model.aligenie.AligenieProduct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;

View File

@ -3,7 +3,7 @@ package cc.iotkit.manager.controller.api;
import cc.iotkit.dao.AppInfoRepository;
import cc.iotkit.dao.HomeRepository;
import cc.iotkit.dao.UserInfoRepository;
import cc.iotkit.manager.utils.AuthUtil;
import cc.iotkit.utils.AuthUtil;
import cc.iotkit.model.AppInfo;
import cc.iotkit.model.space.Home;
import cc.iotkit.model.UserInfo;

View File

@ -6,7 +6,7 @@ import cc.iotkit.dao.SpaceDeviceRepository;
import cc.iotkit.manager.model.vo.AppPageNode;
import cc.iotkit.manager.service.AppDesignService;
import cc.iotkit.manager.service.DeviceService;
import cc.iotkit.manager.utils.AuthUtil;
import cc.iotkit.utils.AuthUtil;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.space.SpaceDevice;
import io.swagger.annotations.ApiImplicitParam;

View File

@ -4,7 +4,7 @@ import cc.iotkit.dao.HomeRepository;
import cc.iotkit.dao.SpaceRepository;
import cc.iotkit.dao.UserActionLogRepository;
import cc.iotkit.dao.UserInfoRepository;
import cc.iotkit.manager.utils.AuthUtil;
import cc.iotkit.utils.AuthUtil;
import cc.iotkit.model.space.Home;
import cc.iotkit.model.space.Space;
import cc.iotkit.model.UserActionLog;

View File

@ -3,7 +3,7 @@ package cc.iotkit.manager.controller.api;
import cc.iotkit.dao.*;
import cc.iotkit.manager.model.vo.SpaceDeviceVo;
import cc.iotkit.manager.service.SpaceDeviceService;
import cc.iotkit.manager.utils.AuthUtil;
import cc.iotkit.utils.AuthUtil;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.product.Product;
import cc.iotkit.model.space.Space;

View File

@ -1,7 +1,7 @@
package cc.iotkit.manager.service;
import cc.iotkit.common.exception.BizException;
import cc.iotkit.manager.utils.AuthUtil;
import cc.iotkit.utils.AuthUtil;
import cc.iotkit.model.Owned;
import cc.iotkit.model.device.DeviceInfo;
import org.apache.commons.lang3.StringUtils;

View File

@ -42,7 +42,7 @@ aliyun:
sa-token:
# token名称 (同时也是cookie名称)
token-name: satoken
token-name: token
# token有效期单位s 默认30天, -1代表永不过期
timeout: 2592000
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒

View File

@ -42,7 +42,7 @@ aliyun:
sa-token:
# token名称 (同时也是cookie名称)
token-name: satoken
token-name: token
# token有效期单位s 默认30天, -1代表永不过期
timeout: 2592000
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒

View File

@ -48,6 +48,12 @@
<artifactId>dao</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -2,10 +2,12 @@ package cc.iotkit.oauth.controller;
import cc.iotkit.common.Constants;
import cc.iotkit.common.utils.CodecUtil;
import cc.iotkit.common.utils.ReflectUtil;
import cc.iotkit.dao.OauthClientCache;
import cc.iotkit.dao.UserInfoCache;
import cc.iotkit.model.OauthClient;
import cc.iotkit.model.UserInfo;
import cc.iotkit.oauth.vo.UserInfoVo;
import cc.iotkit.utils.SoMap;
import cn.dev33.satoken.stp.SaLoginConfig;
import cn.dev33.satoken.stp.StpUtil;
@ -63,15 +65,15 @@ public class AuthClientController {
.toString();
SoMap so = SoMap.getSoMap().setJsonString(str);
log.info("get token by code result:{}", so);
// code不等于200 代表请求失败
if (so.getInt("code") != 200) {
// 存在code,不是token结构
if (so.getInt("code") != 0) {
return SaResult.error(so.getString("msg"));
}
// 根据openid获取其对应的userId
SoMap data = so.getMap("data");
String uid = getUserIdByOpenid(data.getString("openid"));
String access_token = data.getString("access_token");
SoMap data = new SoMap();
String uid = getUserIdByOpenid(so.getString("openid"));
String access_token = so.getString("access_token");
UserInfo userInfo = userInfoCache.getUserInfo(uid);
data.put("name", userInfo.getNickName());
data.put("uid", uid);
@ -92,34 +94,17 @@ public class AuthClientController {
return new RedirectView(redirect_uri);
}
// 根据 Access-Token 置换相关的资源: 获取账号昵称、头像、性别等信息
@RequestMapping("/getUserinfo")
public SaResult getUserinfo(String accessToken) {
// 调用Server端接口查询开放的资源
String str = OkHttps.sync(serverUrl + "/oauth2/userinfo")
.addBodyPara("access_token", accessToken)
.post()
.getBody()
.toString();
SoMap so = SoMap.getSoMap().setJsonString(str);
// code不等于200 代表请求失败
if (so.getInt("code") != 200) {
return SaResult.error(so.getString("msg"));
}
// 返回相关参数 (data=获取到的资源 )
SoMap data = so.getMap("data");
return SaResult.data(data);
}
@GetMapping("/checkLogin")
public SaResult checkLogin() {
try {
StpUtil.checkLogin();
String uid = StpUtil.getLoginId().toString();
UserInfo userInfo = userInfoCache.getUserInfo(uid);
UserInfoVo userVo = new UserInfoVo();
ReflectUtil.copyNoNulls(userInfo, userVo);
return SaResult.ok().setData(userVo);
} catch (Throwable e) {
return SaResult.error("no login");
}
return SaResult.ok();
}
@SneakyThrows

View File

@ -1,25 +1,28 @@
package cc.iotkit.oauth.controller;
import cc.iotkit.common.Constants;
import cc.iotkit.common.utils.CodecUtil;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.dao.UserInfoRepository;
import cc.iotkit.model.UserInfo;
import cc.iotkit.oauth.service.TokenRequestHandler;
import cc.iotkit.utils.AuthUtil;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.oauth2.config.SaOAuth2Config;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Util;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
@Slf4j
@RestController
public class AuthServerController {
@ -28,8 +31,10 @@ public class AuthServerController {
// 处理所有OAuth相关请求
@RequestMapping("/oauth2/*")
public Object request() {
return TokenRequestHandler.serverRequest();
public Object request(HttpServletRequest request) {
Object result = TokenRequestHandler.serverRequest();
log.info("oauth path:{},result:{}", request.getRequestURI(), JsonUtil.toJsonString(result));
return result;
}
// Sa-OAuth2 定制化配置
@ -44,8 +49,7 @@ public class AuthServerController {
UserInfo userInfo = userInfoRepository.findByUid(name);
if (userInfo != null) {
String secret = userInfo.getSecret();
String encodePwd = CodecUtil.aesEncrypt(pwd, Constants.ACCOUNT_SECRET);
if (encodePwd.equals(secret)) {
if (AuthUtil.checkPwd(pwd, secret)) {
StpUtil.login(userInfo.getId(), "PC");
return SaResult.ok();
}
@ -94,4 +98,6 @@ public class AuthServerController {
map.put("address", "山东省 青岛市 城阳区");
return SaResult.data(map);
}
}

View File

@ -6,7 +6,6 @@ import cn.dev33.satoken.stp.StpInterface;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
@ -20,10 +19,8 @@ public class StpInterfaceImpl implements StpInterface {
*/
@Override
public List<String> getPermissionList(Object loginId, String loginType) {
// 本list仅做模拟实际项目中要根据具体业务逻辑来查询权限
List<String> list = new ArrayList<String>();
list.add("write");
return list;
UserInfo userInfo = userInfoCache.getUserInfo(loginId.toString());
return userInfo.getPermissions();
}
/**

View File

@ -8,7 +8,13 @@ import cn.dev33.satoken.oauth2.config.SaOAuth2Config;
import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Consts;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Handle;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Util;
import cn.dev33.satoken.oauth2.model.AccessTokenModel;
import cn.dev33.satoken.oauth2.model.ClientTokenModel;
import cn.dev33.satoken.oauth2.model.RequestAuthModel;
import cn.dev33.satoken.oauth2.model.SaClientModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
public class TokenRequestHandler {
@ -25,9 +31,9 @@ public class TokenRequestHandler {
return SaOAuth2Handle.authorize(req, res, cfg);
}
} else if (req.isPath(SaOAuth2Consts.Api.token) && req.isParam(SaOAuth2Consts.Param.grant_type, SaOAuth2Consts.GrantType.authorization_code)) {
return SaOAuth2Handle.token(req, res, cfg);
return token(req, res, cfg);
} else if (req.isPath(SaOAuth2Consts.Api.token) && req.isParam(SaOAuth2Consts.Param.grant_type, SaOAuth2Consts.GrantType.refresh_token)) {
return SaOAuth2Handle.refreshToken(req);
return refreshToken(req);
} else if (req.isPath(SaOAuth2Consts.Api.revoke)) {
return SaOAuth2Handle.revokeToken(req);
} else if (req.isPath(SaOAuth2Consts.Api.doLogin)) {
@ -46,17 +52,65 @@ public class TokenRequestHandler {
if (!cfg.getIsPassword() || !cm.isPassword && !cm.isAutoMode) {
throw new SaOAuth2Exception("暂未开放的授权模式");
} else {
return SaOAuth2Handle.password(req, res, cfg);
return password(req, res, cfg);
}
} else if (req.isPath(SaOAuth2Consts.Api.token) && req.isParam(SaOAuth2Consts.Param.grant_type, SaOAuth2Consts.GrantType.client_credentials)) {
cm = SaOAuth2Handle.currClientModel();
if (!cfg.getIsClient() || !cm.isClient && !cm.isAutoMode) {
throw new SaOAuth2Exception("暂未开放的授权模式");
} else {
return SaOAuth2Handle.clientToken(req, res, cfg);
return clientToken(req, res, cfg);
}
} else {
return "{\"msg\": \"not handle\"}";
}
}
public static Object token(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
String code = req.getParamNotNull(SaOAuth2Consts.Param.code);
String clientId = req.getParamNotNull(SaOAuth2Consts.Param.client_id);
String clientSecret = req.getParamNotNull(SaOAuth2Consts.Param.client_secret);
String redirectUri = req.getParam(SaOAuth2Consts.Param.redirect_uri);
SaOAuth2Util.checkGainTokenParam(code, clientId, clientSecret, redirectUri);
AccessTokenModel token = SaOAuth2Util.generateAccessToken(code);
return token.toLineMap();
}
public static Object refreshToken(SaRequest req) {
String clientId = req.getParamNotNull(SaOAuth2Consts.Param.client_id);
String clientSecret = req.getParamNotNull(SaOAuth2Consts.Param.client_secret);
String refreshToken = req.getParamNotNull(SaOAuth2Consts.Param.refresh_token);
SaOAuth2Util.checkRefreshTokenParam(clientId, clientSecret, refreshToken);
return SaOAuth2Util.refreshAccessToken(refreshToken).toLineMap();
}
public static Object password(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
String username = req.getParamNotNull(SaOAuth2Consts.Param.username);
String password = req.getParamNotNull(SaOAuth2Consts.Param.password);
String clientId = req.getParamNotNull(SaOAuth2Consts.Param.client_id);
String scope = req.getParam(SaOAuth2Consts.Param.scope, "");
SaOAuth2Util.checkContract(clientId, scope);
SaHolder.getStorage().set(StpUtil.stpLogic.splicingKeyJustCreatedSave(), "no-token");
Object retObj = cfg.getDoLoginHandle().apply(username, password);
if (!StpUtil.isLogin()) {
return retObj;
} else {
RequestAuthModel ra = new RequestAuthModel();
ra.clientId = clientId;
ra.loginId = StpUtil.getLoginId();
ra.scope = scope;
AccessTokenModel at = SaOAuth2Util.generateAccessToken(ra, true);
return at.toLineMap();
}
}
public static Object clientToken(SaRequest req, SaResponse res, SaOAuth2Config cfg) {
String clientId = req.getParamNotNull(SaOAuth2Consts.Param.client_id);
String clientSecret = req.getParamNotNull(SaOAuth2Consts.Param.client_secret);
String scope = req.getParam(SaOAuth2Consts.Param.scope);
SaOAuth2Util.checkContract(clientId, scope);
SaOAuth2Util.checkClientSecret(clientId, clientSecret);
ClientTokenModel ct = SaOAuth2Util.generateClientToken(clientId, scope);
return ct.toLineMap();
}
}

View File

@ -0,0 +1,70 @@
package cc.iotkit.oauth.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserInfoVo {
/**
*
*/
private String uid;
/**
*
*/
private String nickName;
/**
* 0- 1-male,2-female
*/
private Integer gender;
/**
*
*/
private String avatarUrl;
private String email;
private String address;
/**
* Id
*/
private String currHomeId;
/**
*
* 0:
* 1:
*/
private Integer type;
/**
*
*/
private List<String> roles = new ArrayList<>();
/**
*
*/
private List<String> permissions = new ArrayList<>();
/**
* 使
* :Constants.THIRD_PLATFORM
*/
private List<String> usePlatforms = new ArrayList<>();
}

View File

@ -1,9 +1,10 @@
package cc.iotkit.manager.utils;
package cc.iotkit.utils;
import cc.iotkit.common.Constants;
import cc.iotkit.common.utils.CodecUtil;
import cn.dev33.satoken.stp.StpUtil;
import org.apache.commons.lang3.RandomUtils;
import java.util.ArrayList;
import java.util.List;
public class AuthUtil {
@ -28,4 +29,14 @@ public class AuthUtil {
return AuthUtil.getUserRoles().contains(Constants.ROLE_WRITE);
}
public static String enCryptPwd(String pwd) throws Exception {
return CodecUtil.aesEncrypt(CodecUtil.md5Str(pwd) + ":"
+ RandomUtils.nextInt(1000, 9999), Constants.ACCOUNT_SECRET);
}
public static boolean checkPwd(String pwd, String secret) throws Exception {
String code = CodecUtil.aesDecrypt(secret, Constants.ACCOUNT_SECRET);
String[] arr = code.split(":");
return arr.length > 0 && CodecUtil.md5Str(pwd).equals(arr[0]);
}
}

View File

@ -0,0 +1,14 @@
import cc.iotkit.utils.AuthUtil;
import org.junit.Test;
public class GenPwdSecret {
@Test
public void gen() throws Exception {
//生成密码加密内容
String secret = AuthUtil.enCryptPwd("c123456");
System.out.println(secret);
System.out.println(AuthUtil.checkPwd("c123456", secret));
}
}

View File

@ -125,7 +125,7 @@ public class ApiTool {
request = request
.timeout(timeout)
.putHeader("wrap-response", "json")
.putHeader("authorization", "Bearer " + token);
.putHeader("token", token);
AtomicReference<ApiResponse> apiResponse = new AtomicReference<>(
new ApiResponse(500, "", null, System.currentTimeMillis()));