Http request use new plugin.
This commit is contained in:
parent
d2e11a3de7
commit
88818d0816
@ -58,7 +58,7 @@ public abstract class AbstractProtocolAuthService<R> implements ProtocolAuthServ
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateAuthority(IdentityContext identityContext, Permission permission) {
|
||||
public boolean validateAuthority(IdentityContext identityContext, Permission permission) throws AccessException {
|
||||
if (!authConfigs.isAuthEnabled()) {
|
||||
return true;
|
||||
}
|
||||
|
@ -51,8 +51,9 @@ public interface AuthPluginService {
|
||||
* @param identityContext where we can find the user information.
|
||||
* @param permission permission to auth.
|
||||
* @return Boolean if the user has the resource authority.
|
||||
* @throws AccessException if authentication is failed
|
||||
*/
|
||||
Boolean validateAuthority(IdentityContext identityContext, Permission permission);
|
||||
Boolean validateAuthority(IdentityContext identityContext, Permission permission) throws AccessException;
|
||||
|
||||
/**
|
||||
* AuthPluginService Name which for conveniently find AuthPluginService instance.
|
||||
|
@ -43,7 +43,7 @@ public class HttpProtocolAuthService extends AbstractProtocolAuthService<HttpSer
|
||||
|
||||
private final HttpIdentityContextBuilder identityContextBuilder;
|
||||
|
||||
protected HttpProtocolAuthService(AuthConfigs authConfigs) {
|
||||
public HttpProtocolAuthService(AuthConfigs authConfigs) {
|
||||
super(authConfigs);
|
||||
resourceParserMap = new HashMap<>(2);
|
||||
identityContextBuilder = new HttpIdentityContextBuilder(authConfigs);
|
||||
|
@ -19,8 +19,10 @@ package com.alibaba.nacos.console.security.nacos;
|
||||
import com.alibaba.nacos.api.common.Constants;
|
||||
import com.alibaba.nacos.api.remote.request.Request;
|
||||
import com.alibaba.nacos.auth.AuthManager;
|
||||
import com.alibaba.nacos.auth.exception.AccessException;
|
||||
import com.alibaba.nacos.auth.AuthPluginService;
|
||||
import com.alibaba.nacos.auth.api.IdentityContext;
|
||||
import com.alibaba.nacos.auth.api.Permission;
|
||||
import com.alibaba.nacos.auth.exception.AccessException;
|
||||
import com.alibaba.nacos.auth.model.User;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.config.server.auth.RoleInfo;
|
||||
@ -39,6 +41,8 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -48,7 +52,21 @@ import java.util.List;
|
||||
* @since 1.2.0
|
||||
*/
|
||||
@Component
|
||||
public class NacosAuthManager implements AuthManager {
|
||||
@SuppressWarnings("PMD.ServiceOrDaoClassShouldEndWithImplRule")
|
||||
public class NacosAuthManager implements AuthManager, AuthPluginService {
|
||||
|
||||
private static final String AUTH_PLUGIN_TYPE = "nacos";
|
||||
|
||||
private static final String USER_IDENTITY_PARAM_KEY = "user";
|
||||
|
||||
private static final List<String> IDENTITY_NAMES = new LinkedList<String>() {
|
||||
{
|
||||
add(AuthConstants.AUTHORIZATION_HEADER);
|
||||
add(Constants.ACCESS_TOKEN);
|
||||
add(AuthConstants.PARAM_USERNAME);
|
||||
add(AuthConstants.PARAM_PASSWORD);
|
||||
}
|
||||
};
|
||||
|
||||
@Autowired
|
||||
private JwtTokenManager tokenManager;
|
||||
@ -63,34 +81,8 @@ public class NacosAuthManager implements AuthManager {
|
||||
public User login(Object request) throws AccessException {
|
||||
HttpServletRequest req = (HttpServletRequest) request;
|
||||
String token = resolveToken(req);
|
||||
if (StringUtils.isBlank(token)) {
|
||||
throw new AccessException("user not found!");
|
||||
}
|
||||
|
||||
try {
|
||||
tokenManager.validateToken(token);
|
||||
} catch (ExpiredJwtException e) {
|
||||
throw new AccessException("token expired!");
|
||||
} catch (Exception e) {
|
||||
throw new AccessException("token invalid!");
|
||||
}
|
||||
|
||||
Authentication authentication = tokenManager.getAuthentication(token);
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
|
||||
String username = authentication.getName();
|
||||
NacosUser user = new NacosUser();
|
||||
user.setUserName(username);
|
||||
user.setToken(token);
|
||||
List<RoleInfo> roleInfoList = roleService.getRoles(username);
|
||||
if (roleInfoList != null) {
|
||||
for (RoleInfo roleInfo : roleInfoList) {
|
||||
if (roleInfo.getRole().equals(AuthConstants.GLOBAL_ADMIN_ROLE)) {
|
||||
user.setGlobalAdmin(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
validate0(token);
|
||||
NacosUser user = getNacosUser(token);
|
||||
req.getSession().setAttribute(RequestUtil.NACOS_USER_KEY, user);
|
||||
return user;
|
||||
}
|
||||
@ -99,46 +91,39 @@ public class NacosAuthManager implements AuthManager {
|
||||
public User loginRemote(Object request) throws AccessException {
|
||||
Request req = (Request) request;
|
||||
String token = resolveToken(req);
|
||||
if (StringUtils.isBlank(token)) {
|
||||
throw new AccessException("user not found!");
|
||||
}
|
||||
|
||||
try {
|
||||
tokenManager.validateToken(token);
|
||||
} catch (ExpiredJwtException e) {
|
||||
throw new AccessException("token expired!");
|
||||
} catch (Exception e) {
|
||||
throw new AccessException("token invalid!");
|
||||
}
|
||||
|
||||
Authentication authentication = tokenManager.getAuthentication(token);
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
|
||||
String username = authentication.getName();
|
||||
NacosUser user = new NacosUser();
|
||||
user.setUserName(username);
|
||||
user.setToken(token);
|
||||
List<RoleInfo> roleInfoList = roleService.getRoles(username);
|
||||
if (roleInfoList != null) {
|
||||
for (RoleInfo roleInfo : roleInfoList) {
|
||||
if (roleInfo.getRole().equals(AuthConstants.GLOBAL_ADMIN_ROLE)) {
|
||||
user.setGlobalAdmin(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return user;
|
||||
validate0(token);
|
||||
return getNacosUser(token);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void auth(Permission permission, User user) throws AccessException {
|
||||
if (Loggers.AUTH.isDebugEnabled()) {
|
||||
Loggers.AUTH.debug("auth permission: {}, user: {}", permission, user);
|
||||
auth0(permission, user);
|
||||
}
|
||||
|
||||
if (!roleService.hasPermission(user.getUserName(), permission)) {
|
||||
throw new AccessException("authorization failed!");
|
||||
@Override
|
||||
public Collection<String> identityNames() {
|
||||
return IDENTITY_NAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateIdentity(IdentityContext identityContext) throws AccessException {
|
||||
String token = resolveToken(identityContext);
|
||||
validate0(token);
|
||||
NacosUser user = getNacosUser(token);
|
||||
identityContext.setParameter(USER_IDENTITY_PARAM_KEY, user);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean validateAuthority(IdentityContext identityContext, Permission permission) throws AccessException {
|
||||
NacosUser user = (NacosUser) identityContext.getParameter(USER_IDENTITY_PARAM_KEY);
|
||||
auth0(permission, user);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthServiceName() {
|
||||
return AUTH_PLUGIN_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -173,7 +158,20 @@ public class NacosAuthManager implements AuthManager {
|
||||
String password = request.getHeader(AuthConstants.PARAM_PASSWORD);
|
||||
bearerToken = resolveTokenFromUser(userName, password);
|
||||
}
|
||||
return bearerToken;
|
||||
}
|
||||
|
||||
private String resolveToken(IdentityContext identityContext) throws AccessException {
|
||||
String bearerToken = identityContext.getParameter(AuthConstants.AUTHORIZATION_HEADER, StringUtils.EMPTY);
|
||||
if (StringUtils.isNotBlank(bearerToken) && bearerToken.startsWith(AuthConstants.TOKEN_PREFIX)) {
|
||||
return bearerToken.substring(7);
|
||||
}
|
||||
bearerToken = identityContext.getParameter(Constants.ACCESS_TOKEN, StringUtils.EMPTY);
|
||||
if (StringUtils.isBlank(bearerToken)) {
|
||||
String userName = (String) identityContext.getParameter(AuthConstants.PARAM_USERNAME);
|
||||
String password = (String) identityContext.getParameter(AuthConstants.PARAM_PASSWORD);
|
||||
bearerToken = resolveTokenFromUser(userName, password);
|
||||
}
|
||||
return bearerToken;
|
||||
}
|
||||
|
||||
@ -196,4 +194,48 @@ public class NacosAuthManager implements AuthManager {
|
||||
|
||||
return tokenManager.createToken(finalName);
|
||||
}
|
||||
|
||||
private void validate0(String token) throws AccessException {
|
||||
if (StringUtils.isBlank(token)) {
|
||||
throw new AccessException("user not found!");
|
||||
}
|
||||
|
||||
try {
|
||||
tokenManager.validateToken(token);
|
||||
} catch (ExpiredJwtException e) {
|
||||
throw new AccessException("token expired!");
|
||||
} catch (Exception e) {
|
||||
throw new AccessException("token invalid!");
|
||||
}
|
||||
}
|
||||
|
||||
private NacosUser getNacosUser(String token) {
|
||||
Authentication authentication = tokenManager.getAuthentication(token);
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
|
||||
String username = authentication.getName();
|
||||
NacosUser user = new NacosUser();
|
||||
user.setUserName(username);
|
||||
user.setToken(token);
|
||||
List<RoleInfo> roleInfoList = roleService.getRoles(username);
|
||||
if (roleInfoList != null) {
|
||||
for (RoleInfo roleInfo : roleInfoList) {
|
||||
if (roleInfo.getRole().equals(AuthConstants.GLOBAL_ADMIN_ROLE)) {
|
||||
user.setGlobalAdmin(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
private void auth0(Permission permission, User user) throws AccessException {
|
||||
if (Loggers.AUTH.isDebugEnabled()) {
|
||||
Loggers.AUTH.debug("auth permission: {}, user: {}", permission, user);
|
||||
}
|
||||
|
||||
if (!roleService.hasPermission(user.getUserName(), permission)) {
|
||||
throw new AccessException("authorization failed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package com.alibaba.nacos.core.auth;
|
||||
|
||||
import com.alibaba.nacos.auth.config.AuthConfigs;
|
||||
import com.alibaba.nacos.core.code.ControllerMethodsCache;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -29,9 +31,9 @@ import org.springframework.context.annotation.Configuration;
|
||||
public class AuthConfig {
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean authFilterRegistration() {
|
||||
public FilterRegistrationBean authFilterRegistration(AuthFilter authFilter) {
|
||||
FilterRegistrationBean<AuthFilter> registration = new FilterRegistrationBean<>();
|
||||
registration.setFilter(authFilter());
|
||||
registration.setFilter(authFilter);
|
||||
registration.addUrlPatterns("/*");
|
||||
registration.setName("authFilter");
|
||||
registration.setOrder(6);
|
||||
@ -40,7 +42,7 @@ public class AuthConfig {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthFilter authFilter() {
|
||||
return new AuthFilter();
|
||||
public AuthFilter authFilter(AuthConfigs authConfigs, ControllerMethodsCache methodsCache) {
|
||||
return new AuthFilter(authConfigs, methodsCache);
|
||||
}
|
||||
}
|
||||
|
@ -16,20 +16,20 @@
|
||||
|
||||
package com.alibaba.nacos.core.auth;
|
||||
|
||||
import com.alibaba.nacos.auth.AuthManager;
|
||||
import com.alibaba.nacos.auth.HttpProtocolAuthService;
|
||||
import com.alibaba.nacos.auth.annotation.Secured;
|
||||
import com.alibaba.nacos.auth.api.IdentityContext;
|
||||
import com.alibaba.nacos.auth.api.Permission;
|
||||
import com.alibaba.nacos.auth.api.Resource;
|
||||
import com.alibaba.nacos.auth.config.AuthConfigs;
|
||||
import com.alibaba.nacos.auth.exception.AccessException;
|
||||
import com.alibaba.nacos.auth.api.Permission;
|
||||
import com.alibaba.nacos.auth.parser.ResourceParser;
|
||||
import com.alibaba.nacos.common.utils.ExceptionUtil;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import com.alibaba.nacos.core.code.ControllerMethodsCache;
|
||||
import com.alibaba.nacos.sys.env.Constants;
|
||||
import com.alibaba.nacos.core.utils.Loggers;
|
||||
import com.alibaba.nacos.core.utils.WebUtils;
|
||||
import com.alibaba.nacos.common.utils.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import com.alibaba.nacos.sys.env.Constants;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
@ -51,16 +51,20 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
*/
|
||||
public class AuthFilter implements Filter {
|
||||
|
||||
@Autowired
|
||||
private AuthConfigs authConfigs;
|
||||
private final AuthConfigs authConfigs;
|
||||
|
||||
@Autowired
|
||||
private AuthManager authManager;
|
||||
private final ControllerMethodsCache methodsCache;
|
||||
|
||||
@Autowired
|
||||
private ControllerMethodsCache methodsCache;
|
||||
private final HttpProtocolAuthService protocolAuthService;
|
||||
|
||||
private Map<Class<? extends ResourceParser>, ResourceParser> parserInstance = new ConcurrentHashMap<>();
|
||||
private final Map<Class<? extends ResourceParser>, ResourceParser> parserInstance = new ConcurrentHashMap<>();
|
||||
|
||||
public AuthFilter(AuthConfigs authConfigs, ControllerMethodsCache methodsCache) {
|
||||
this.authConfigs = authConfigs;
|
||||
this.methodsCache = methodsCache;
|
||||
this.protocolAuthService = new HttpProtocolAuthService(authConfigs);
|
||||
this.protocolAuthService.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
@ -114,22 +118,19 @@ public class AuthFilter implements Filter {
|
||||
}
|
||||
|
||||
Secured secured = method.getAnnotation(Secured.class);
|
||||
Resource resource = protocolAuthService.parseResource(req, secured);
|
||||
IdentityContext identityContext = protocolAuthService.parseIdentity(req);
|
||||
boolean result = protocolAuthService.validateIdentity(identityContext);
|
||||
if (!result) {
|
||||
// TODO Get reason of failure
|
||||
throw new AccessException("Validate Identity failed.");
|
||||
}
|
||||
String action = secured.action().toString();
|
||||
String resource = secured.resource();
|
||||
|
||||
if (StringUtils.isBlank(resource)) {
|
||||
ResourceParser parser = getResourceParser(secured.parser());
|
||||
resource = parser.parseName(req);
|
||||
result = protocolAuthService.validateAuthority(identityContext, new Permission(resource, action));
|
||||
if (!result) {
|
||||
// TODO Get reason of failure
|
||||
throw new AccessException("Validate Authority failed.");
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(resource)) {
|
||||
// deny if we don't find any resource:
|
||||
throw new AccessException("resource name invalid!");
|
||||
}
|
||||
|
||||
Resource resourceObj = new Resource(null, null, resource, secured.signType(), null);
|
||||
authManager.auth(new Permission(resourceObj, action), authManager.login(req));
|
||||
|
||||
}
|
||||
chain.doFilter(request, response);
|
||||
} catch (AccessException e) {
|
||||
@ -144,14 +145,4 @@ public class AuthFilter implements Filter {
|
||||
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Server failed," + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private ResourceParser getResourceParser(Class<? extends ResourceParser> parseClass)
|
||||
throws IllegalAccessException, InstantiationException {
|
||||
ResourceParser parser = parserInstance.get(parseClass);
|
||||
if (parser == null) {
|
||||
parser = parseClass.newInstance();
|
||||
parserInstance.put(parseClass, parser);
|
||||
}
|
||||
return parser;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user