All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.nerv.security.provider.UrlAccessDecisionManager Maven / Gradle / Ivy

There is a newer version: 3.0.0
Show newest version
package io.nerv.security.provider;

import cn.hutool.core.util.StrUtil;
import io.nerv.core.enums.BizCodeEnum;
import io.nerv.properties.EvaConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Collection;

@Slf4j
@Component
public class UrlAccessDecisionManager implements AccessDecisionManager {

    @Value("${eva.security.permit}")
    private String[] permit;

    @Autowired
    private EvaConfig evaConfig;

    // configAttributes 为MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法返回的结果,
    // authentication 是释循环添加到 GrantedAuthority 对象中的权限信息集合.
    // object 包含客户端发起的请求的requset信息,可转换为 HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
    // configAttributes 为 UrlFilterInvocationSecurityMetadataSource 的getAttributes(Object object)这个方法返回的结果,
    // 此方法是为了判定用户请求的url 是否在权限表中,如果在权限表中,则返回给 decide 方法,用来判定用户是否有此权限。如果不在权限表中则放行。
    @Override
    public void decide(Authentication authentication, Object o,
                       Collection collection) throws AccessDeniedException {
        log.info("collection=" + collection);

        HttpServletRequest request = ((FilterInvocation) o).getHttpRequest();
        String requestUrl = ((FilterInvocation) o).getRequestUrl();
        log.info("requestUrl : " + requestUrl);

        // 可访问资源放行
        for (var permitUrl : permit){
            var urlMatcher = new AntPathRequestMatcher(permitUrl);

            if (urlMatcher.matches(request) ||
                    StrUtil.equals(requestUrl,permitUrl)) return;
        }

        if(evaConfig.getResourcePermission().isEnable()) {
            if (evaConfig.getResourcePermission().isStrict()) {
                /**
                 * 严格模式, 判断 登录角色 请求的资源 是否与 资源需要的角色 一致
                 * 一致 return 放行
                 * 不一致 抛出权限不足异常
                 */
                for (ConfigAttribute configAttribute : collection) {
                    // 当前请求需要的权限
                    String url = configAttribute.getAttribute();

                    var urlMatcher = new AntPathRequestMatcher(url);

                    if (urlMatcher.matches(request) ||
                            StrUtil.equals(requestUrl, url)) return;
                }
                // en for
            } else {
                /**
                 * 简单模式 , 判断 登录角色 是否 所请求资源 的授权列表里
                 * 存在 放行
                 * 不存在 返回权限不足
                 */
                Collection authorities = authentication.getAuthorities();

                for (ConfigAttribute configAttribute : collection) {

                    String role = configAttribute.getAttribute();

                    for (GrantedAuthority grantedAuthority: authorities){
                        if (grantedAuthority.getAuthority().equals(role)){
                            return;
                        }
                    }
                }
                // end for
            }
        } else {
            return;
        }

        throw new AccessDeniedException(BizCodeEnum.PERMISSION_DENY.getName());
    }

    @Override
    public boolean supports(ConfigAttribute configAttribute) {
        return true;
    }

    @Override
    public boolean supports(Class aClass) {
        return true;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy