Spring security + Spring boot 可直接使用的RBAC权限控制SDK

根据接口api 鉴权 登录获取token
POM

    <dependencies>

        <!-- 引入JWT -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.7.0</version>
        </dependency>

        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>3.6.0</version>
        </dependency>
        <!-- apache httpclient组件 -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.6</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.11</version>
        </dependency>
        <!-- 与数据库操作相关的依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <!-- 使用数据源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.14</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
         
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>1.7.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>4.1.6</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
            <scope>provided</scope>
        </dependency>
        <!--引入熔断器-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

        <!--<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>-->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
        </dependency>


    </dependencies>

TokenUtils.java

@Component
public class TokenProvider {

 //验证JWT是否合法
    public boolean validateToken(String token) {
        try {
            Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token);
            return true;
        } catch (SignatureException e) {
            log.info("Invalid JWT signature.");
            log.trace("Invalid JWT signature trace: {}", e);
        } catch (MalformedJwtException e) {
            log.info("Invalid JWT token.");
            log.trace("Invalid JWT token trace: {}", e);
        } catch (ExpiredJwtException e) {
            log.info("Expired JWT token.");
            log.trace("Expired JWT token trace: {}", e);
        } catch (UnsupportedJwtException e) {
            log.info("Unsupported JWT token.");
            log.trace("Unsupported JWT token trace: {}", e);
        } catch (IllegalArgumentException e) {
            log.info("JWT token compact of handler are invalid.");
            log.trace("JWT token compact of handler are invalid trace: {}", e);
        }
        return false;
    }

    //创建JWT
    public String createToken(String userID, String userName, int refreshTimes) {
        long now = (new Date()).getTime();
        Date validity = new Date(now + this.expiration);
        Map<String, Object> claims = new HashMap<String, Object>();
        claims.put(CLAIM_KEY_ISSUER, "EYE-INSIGHT");
        claims.put(CLAIM_KEY_ISSUED_AT, System.currentTimeMillis());
        claims.put(CLAIM_KEY_SUBJECT, userID);
        claims.put(CLAIM_KEY_USER_ID, userID);
        claims.put(CLAIM_KEY_USER_NAME, userName);
        claims.put(CLAIM_KEY_REFRESH_TIMES, refreshTimes);
        return Jwts.builder().signWith(SignatureAlgorithm.HS512, secretKey).setClaims(claims).setExpiration(validity).compact();
    }

}
SercurityConfig.java
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SercurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
    private DaoSecurityMetadataSource daoSecurityMetadataSource;

    @Autowired
    private UrlAccessDecisionManager decisionManager;

 //创建jwt认证的Filter Bean
    @Bean
    public JWTAuthorizeFilter jwtAuthorizeFilterBean() throws Exception {
        return new JWTAuthorizeFilter();
    }

    @Override
    public void configure(WebSecurity web) {
        String[] split = antMatchers.split(",");
        web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**")
                .antMatchers("/health")
                .antMatchers("/swagger-ui.html")
                .antMatchers("/swagger-resources/**")
                .antMatchers("/webjars/springfox-swagger-ui/**/*.		{js,css,html}")
                .antMatchers(split);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        log.info("EnableAuthentication:" + authentication);
        http
                .csrf().disable()
                .headers().frameOptions().disable()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        if (authentication.equals("enable")) {
            //对指定的请求进行权限设置
            http
                    // 除上面外的所有请求全部需要鉴权认证
                    .authorizeRequests()
                    // 自定义FilterInvocationSecurityMetadataSource
                    .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
                        @Override
                        public <O extends FilterSecurityInterceptor> O postProcess(O o) {
                            o.setSecurityMetadataSource(daoSecurityMetadataSource);
                            o.setAccessDecisionManager(decisionManager);
                            return o;
                        }
                    })
                    //实现将未认证过的请求,直接返回401,而不返回403
                    .and()
                    .exceptionHandling().authenticationEntryPoint(authEntrypoint)
                    .and()
                    //在HttpSecurity中增加Filter Bean,必须传入Singletone的bean
                    .addFilterBefore(jwtAuthorizeFilterBean(), UsernamePasswordAuthenticationFilter.class)
                    //对于Actuator的Endpoint启动Basic认证
                    .authorizeRequests()
                    .antMatchers("/admin/shutdown").authenticated().and().httpBasic();
        }

    }
}
DaoSecurityMetadataSource.java
@Component
public class DaoSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
  @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
        FilterInvocation fi = (FilterInvocation) o;
        List<SysRole> neededRoles = this.getRequestNeededRoles(fi.getRequest().getMethod(), fi.getRequestUrl());
        if (neededRoles != null) {
            return SecurityConfig.createList(neededRoles.stream().map(role -> role.getRolename()
            ).collect(Collectors.toList()).toArray(new String[]{}));
        }
        return SecurityConfig.createList("ROLE_LOGIN");
    }
}
UrlAccessDecisionManager.java
@Component
public class UrlAccessDecisionManager implements AccessDecisionManager {

  /**
     * @param auth 用户的权限
     * @param o
     * @param cas  路径所需要的权限
     */
    @Override
    public void decide(Authentication auth, Object o, Collection<ConfigAttribute> cas) {
        Iterator<ConfigAttribute> iterator = cas.iterator();
        while (iterator.hasNext()) {
            ConfigAttribute ca = iterator.next();
            //当前请求需要的权限
            String needRole = ca.getAttribute();
            if ("ROLE_LOGIN".equals(needRole)) {
                if (auth instanceof AnonymousAuthenticationToken) {
                    throw new BadCredentialsException("未登录");
                } else if (auth instanceof UsernamePasswordAuthenticationToken) {
                    //登录成功 该url没有绑定权限 默认登录即可访问
                    return;
                } else {
                    throw new RuntimeException("权限不足!?");
                }
            }
            //当前用户所具有的权限
            Collection<? extends GrantedAuthority> authorities = auth.getAuthorities();
            for (GrantedAuthority authority : authorities) {
                //超级管理员直接跳过
                if (authority.getAuthority().equals("ROLE_SUPER_ADMIN")) {
                    return;
                }
                if (authority.getAuthority().equals(needRole)) {
                    return;
                }
            }
        }
        throw new AccessDeniedException("权限不足!");

    }

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

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

详细源码请参考 https://gitee.com/scriptcode/spring-security-token.git

以上源代码直接引入项目即可为项目注入权限控制功能


@MapperScan(basePackages = {"com.xxx.xxx.*", "com.xxx.rbac.*"})//扫描mybatis接口
@SpringBootApplication(scanBasePackages = {"com.xxx.xxx.*", "com.xxx.rbac.*"})
public class EyeInsightApplication {
			main()
}

java讨论群:931243010

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值