Skip to content

Commit

Permalink
feat($AuthCenter): support admin authorization
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnymillergh committed Dec 28, 2020
1 parent 036d5e6 commit 6e87a2e
Show file tree
Hide file tree
Showing 12 changed files with 78 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, Au
.filter(role -> StrUtil.equals("admin", role.getName()))
.map(GetRoleListByUserIdResponse.Role::getId).collectList()
.switchIfEmpty(getRoleListByUserIdResponseFlux
.map(GetRoleListByUserIdResponse.Role::getId)
.collectList());
.map(GetRoleListByUserIdResponse.Role::getId)
.collectList());

// Get permission list based on the Mono<List<Long>>
// TODO: auth-center should respond /** for role "admin"
// auth-center will respond /** for role "admin"
Mono<GetPermissionListByRoleIdListResponse> getPermissionListByRoleIdListResponseMono = roleIdListMono.flatMap(
roleIdList -> {
GetPermissionListByRoleIdListPayload payload = new GetPermissionListByRoleIdListPayload();
Expand All @@ -82,14 +82,15 @@ public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, Au
val path = request.getURI().getPath();
val userPrincipal = mapper.getT2();
for (val buttonPermission : buttonPermissionList) {
// FIXME: currently, the `method` in permission is useless
if (antPathMatcher.match(buttonPermission.getUrl(), path)) {
log.info("Authorization success! Resource [{}] {} is accessible for user(username: {})",
request.getMethod(), request.getURI(), userPrincipal.getUsername());
request.getMethod(), request.getURI(), userPrincipal.getUsername());
return new AuthorizationDecision(true);
}
}
log.warn("Authorization failure! Resource [{}] {} is inaccessible for user(username: {})",
request.getMethod(), request.getURI(), userPrincipal.getUsername());
request.getMethod(), request.getURI(), userPrincipal.getUsername());
return new AuthorizationDecision(false);
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.authorization.ReactiveAuthorizationManager;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
Expand Down Expand Up @@ -63,8 +62,6 @@ SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http,
.authenticationEntryPoint(serverAuthenticationEntryPoint)
.accessDeniedHandler(serverAccessDeniedHandler)
.and()
// TODO: this filter might be useless, since its order is -500
.addFilterBefore(accessLogFilter, SecurityWebFiltersOrder.AUTHENTICATION)
// Authentication
.authenticationManager(reactiveAuthenticationManager)
.securityContextRepository(serverSecurityContextRepository)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
import com.jmsoftware.maf.authcenter.permission.entity.PermissionPersistence;
import com.jmsoftware.maf.authcenter.permission.mapper.PermissionMapper;
import com.jmsoftware.maf.authcenter.permission.service.PermissionService;
import com.jmsoftware.maf.authcenter.role.service.RoleService;
import com.jmsoftware.maf.authcenter.universal.configuration.ProjectProperty;
import com.jmsoftware.maf.common.bean.ResponseBodyBean;
import com.jmsoftware.maf.common.domain.authcenter.permission.GetPermissionListByRoleIdListPayload;
import com.jmsoftware.maf.common.domain.authcenter.permission.GetPermissionListByRoleIdListResponse;
import com.jmsoftware.maf.common.domain.authcenter.permission.GetPermissionListByUserIdResponse;
import com.jmsoftware.maf.common.domain.authcenter.permission.PermissionType;
import com.jmsoftware.maf.common.domain.springbootstarter.HttpApiResourcesResponse;
import com.jmsoftware.maf.common.exception.BusinessException;
import lombok.NonNull;
Expand Down Expand Up @@ -42,17 +44,28 @@
@Service
@RequiredArgsConstructor
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, PermissionPersistence> implements PermissionService {
private final RoleService roleService;
private final DiscoveryClient discoveryClient;
private final ProjectProperty projectProperty;
private final RestTemplate restTemplate;

@Override
public GetPermissionListByRoleIdListResponse getPermissionListByRoleIdList(@Valid GetPermissionListByRoleIdListPayload payload) {
val permissionList = this.getPermissionListByRoleIdList(payload.getRoleIdList());
val adminRole = roleService.checkAdmin(payload.getRoleIdList());
val response = new GetPermissionListByRoleIdListResponse();
if (adminRole) {
log.warn("Admin role checked. The role can access any resources");
val permission = new GetPermissionListByRoleIdListResponse.Permission();
permission.setUrl("/**");
permission.setType(PermissionType.BUTTON.getType());
permission.setPermissionExpression("admin-permission");
permission.setMethod("*");
response.getPermissionList().add(permission);
return response;
}
val permissionList = this.getPermissionListByRoleIdList(payload.getRoleIdList());
permissionList.forEach(permissionPersistence -> {
GetPermissionListByRoleIdListResponse.Permission permission =
new GetPermissionListByRoleIdListResponse.Permission();
val permission = new GetPermissionListByRoleIdListResponse.Permission();
BeanUtil.copyProperties(permissionPersistence, permission);
response.getPermissionList().add(permission);
});
Expand Down Expand Up @@ -91,7 +104,7 @@ public GetServicesInfoResponse getServicesInfo() throws BusinessException {
val response = new GetServicesInfoResponse();
val mapper = new ObjectMapper();
val ignoredServiceIdList = Lists.newArrayList(projectProperty.getProjectArtifactId(),
"api-gateway", "spring-boot-admin");
"api-gateway", "spring-boot-admin");
log.info("Ignored service ID list: {}", ignoredServiceIdList);
for (String serviceId : serviceIdList) {
if (ignoredServiceIdList.contains(serviceId)) {
Expand All @@ -104,7 +117,7 @@ public GetServicesInfoResponse getServicesInfo() throws BusinessException {
val data = Optional.of(responseBodyBean.getData())
.orElseThrow(() -> new BusinessException("HttpApiResourcesResponse mustn't be null"));
HttpApiResourcesResponse httpApiResourcesResponse = mapper.convertValue(data,
HttpApiResourcesResponse.class);
HttpApiResourcesResponse.class);
GetServicesInfoResponse.ServiceInfo serviceInfo = new GetServicesInfoResponse.ServiceInfo();
serviceInfo.setServiceId(serviceId);
serviceInfo.setHttpApiResources(httpApiResourcesResponse);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import lombok.NonNull;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;

/**
Expand Down Expand Up @@ -33,4 +35,12 @@ public interface RoleService extends IService<RolePersistence> {
* @return the role list by user id
*/
List<RolePersistence> getRoleListByUserId(@NonNull Long userId);

/**
* Check admin boolean.
*
* @param roleIdList the role id list
* @return the boolean
*/
boolean checkAdmin(@NotEmpty List<@NotNull Long> roleIdList);
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
package com.jmsoftware.maf.authcenter.role.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jmsoftware.maf.authcenter.role.entity.RolePersistence;
import com.jmsoftware.maf.authcenter.role.mapper.RoleMapper;
import com.jmsoftware.maf.authcenter.role.service.RoleService;
import com.jmsoftware.maf.common.domain.authcenter.role.GetRoleListByUserIdResponse;
import com.jmsoftware.maf.springbootstarter.configuration.MafConfiguration;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.stream.Collectors;

/**
* <h1>RoleServiceImpl</h1>
Expand All @@ -21,7 +30,10 @@
* @date 2020-05-10 22:39:50
*/
@Service
@RequiredArgsConstructor
public class RoleServiceImpl extends ServiceImpl<RoleMapper, RolePersistence> implements RoleService {
private final MafConfiguration mafConfiguration;

@Override
public GetRoleListByUserIdResponse getRoleList(Long userId) {
val roleList = this.getRoleListByUserId(userId);
Expand All @@ -38,4 +50,19 @@ public GetRoleListByUserIdResponse getRoleList(Long userId) {
public List<RolePersistence> getRoleListByUserId(@NonNull Long userId) {
return this.getBaseMapper().selectRoleListByUserId(userId);
}

@Override
public boolean checkAdmin(@NotEmpty List<@NotNull Long> roleIdList) {
LambdaQueryWrapper<RolePersistence> wrapper = Wrappers.lambdaQuery();
wrapper.select(RolePersistence::getName)
.in(RolePersistence::getId, roleIdList);
val rolePersistenceList = this.list(wrapper);
val roleNameSet = rolePersistenceList
.stream()
.map(RolePersistence::getName)
.filter(roleName -> StrUtil.equals(mafConfiguration.getSuperUserRole(), roleName))
.collect(Collectors.toSet());
// If roleNameSet is not empty (contains "admin")
return CollUtil.isNotEmpty(roleNameSet);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,7 @@ sftp:
private-key-pass-phrase:
session-cache-size: 20
session-wait-timeout: 15000

maf:
configuration:
web-request-log-disabled: false
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public static class Permission {
/**
* The Type.
*/
private Integer type;
private Byte type;
/**
* The Permission expression.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,25 @@ public enum PermissionType {
/**
* Controller
*/
CONTROLLER(0, "Controller"),
CONTROLLER(Byte.valueOf("0"), "Controller"),
/**
* Page
*/
PAGE(1, "Page"),
PAGE(Byte.valueOf("1"), "Page"),
/**
* Button
*/
BUTTON(2, "Button (API)");
BUTTON(Byte.valueOf("2"), "Button (API)");

private final Integer type;
private final Byte type;
private final String description;

PermissionType(Integer type, String description) {
PermissionType(Byte type, String description) {
this.type = type;
this.description = description;
}

public static PermissionType getByType(Integer type) {
public static PermissionType getByType(Byte type) {
PermissionType permissionType = null;
PermissionType[] values = PermissionType.values();
for (PermissionType pt : values) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class MafConfiguration {
* persistent in database.</p>
*/
@NotBlank
private String superUser = "admin";
private String superUserRole = "admin";
/**
* Ignore URLs
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.jmsoftware.maf.springbootstarter.helper.HttpApiScanHelper;
import com.jmsoftware.maf.springbootstarter.helper.IpHelper;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
Expand Down Expand Up @@ -48,7 +49,9 @@ public void postConstruct() {
@ConditionalOnMissingBean
public MafConfiguration mafConfiguration() {
log.warn("Initial bean: {}", MafConfiguration.class.getSimpleName());
return new MafConfiguration();
val mafConfiguration = new MafConfiguration();
log.warn("{}", mafConfiguration);
return mafConfiguration;
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class MafConfiguration {
* persistent in database.</p>
*/
@NotBlank
private String superUser = "admin";
private String superUserRole = "admin";
/**
* Ignore URLs, used by web access log filter and web security.
*/
Expand Down

0 comments on commit 6e87a2e

Please sign in to comment.