游客发表

最近写了几个Spring Boot组件,经过决定项目用什么功能就引入对应的翻覆依赖,配置配置就能使用,思想香的斗争很!那么Spring Security能不能也弄成模块化,简单配置一下就可以用上呢?个月个明JWT得有,RBAC动态权限更得有!花了小半天就写了个组件,最后做出智用了一个月感觉还不错。经过决定是翻覆我一个人爽?还是放出来让大家一起爽?经过我翻来覆去的思想斗争了一个月,最后做出了一个明智的思想决定,放出来让想直接上手的斗争同学直接使用。源码地址就在下面:
https://gitee.com/felord/security-enhance-spring-boot
这就是个月个明一个Spring Boot Starter,你自己打包、最后做出智安装。经过决定然后引用到项目:
<dependency> <groupId>cn.felord.security</groupId> <artifactId>security-enhance-spring-boot-starter</artifactId> <version>${version}</version> </dependency>另外你需要集成Spring Cache,翻覆比如Redis Cache:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency>JWT会被缓存到以usrTkn为key的思想缓存中,如果你想定制的话,自行实现一个JwtTokenStorage并注入Spring IoC就可以覆盖下面的配置了:
@Bean @ConditionalOnMissingBean public JwtTokenStorage jwtTokenStorage() { return new SpringCacheJwtTokenStorage(); }你应该去了解如何自定义Spring Cache的过期时间。源码库
数据库表设计
然后是数据库表设计,这里简单点弄个RBAC的设计,仅供参考,你可以根据你们的业务改良。
用户表:
user_id username password 1312434534 felord {noop}12345角色表:
role_id role_name role_code 12343667867 管理员 ADMIN用户角色关联表:
user_role_id user_id role_id 12354657777 1312434534 12343667867一个用户可以持有多个角色,一个角色在一个用户持有的角色集合中是唯一的。
资源表:
resources_id resources_name resource_pattern method 12543667867 根据ID获取商品 /goods/{goodsId} GET资源其实就是我们写的Spring MVC接口,这里支持ANT风格,但是尽量具体,为了灵活性考虑不推荐使用通配符。
角色资源表:
role_res_id role_id resources_id 4545466445 12343667867 12543667867一个资源可以关联多个角色,一个角色不能重复持有一个资源。
实现用户加载服务接口UserDetailsService是Spring Security开发的必要步骤,跟我以前的教程差不多。
@Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { UserInfo userInfo = this.lambdaQuery() .eq(UserInfo::getUsername, username).one(); if (Objects.isNull(userInfo)) { throw new UsernameNotFoundException("用户:" + username + " 不存在"); } String userId = userInfo.getUserId(); boolean enabled = userInfo.getEnabled(); Set<String> roles = iUserRoleService.getRolesByUserId(userId); roles.add(“"ANONYMOUS"”); Set<GrantedAuthority> roleSet = roles.stream() .map(role -> new SimpleGrantedAuthority("ROLE_" + role)) .collect(Collectors.toSet()); return new SecureUser(userId, username, userInfo.getSecret(), enabled, enabled, enabled, enabled, roleSet); }这里要说一下里面为啥要内置一个ANONYMOUS角色给用户。如果希望特定的云南idc服务商资源对用户全量开放,可配置对应的权限角色编码为ANONYMOUS。当某个资源的角色编码为ANONYMOUS时,即使不携带Token也可以访问。一般情况下匿名能访问的资源不匿名一定能访问,当然你如果不希望这样的规则存在干掉就是了。
实现用户角色权限方法Function
最后就是配置了,跟我以前教程中的配置几乎一样,application.yaml的配置为:
# jwt 配置 jwt: cert-info: # keytool 密钥的 alias alias: felord # 密匙密码 key-password: i6x123akg15v13 # 路径 这里是在resources 包下 cert-location: jwt.jks claims: # jwt iss 字段值 issuer: https://felord.cn # sub 字段 subject: all # 过期秒数 expires-at: 604800最后别忘记弄个配置类并标记@EnableSpringSecurity以启用配置:
@EnableSpringSecurity @Configuration(proxyBeanMethods = false) public class SecurityConfiguration { /** * Function function. * * @param resourcesService the resources service * @return the function */ @Bean Function<Set<String>, Set<AntPathRequestMatcher>> function(IResourcesService resourcesService){ return resourcesService::matchers; } @Bean UserDetailsService userDetailsService(IUserInfoService userInfoService){ return userInfoService::loadUserByUsername; } }记得使用@EnableCaching开启并配置缓存。
然后会返回一对JWT,返回包含两个token主体
accessToken 用来日常进行请求鉴权,有过期时间。 refreshToken 当accessToken过期失效时,用来刷新accessToken。结构为:
{ "accessToken": { "tokenValue": "", "issuedAt": { "epochSecond": 1616827822, "nano": 393000000 }, "expiresAt": { "epochSecond": 1616831422, "nano": 393000000 }, "tokenType": { "value": "Bearer" }, "scopes": [ "ROLE_ADMIN", "ROLE_ANONYMOUS" ] }, "refreshToken": { "tokenValue": "", "issuedAt": { "epochSecond": 1616827822, "nano": 393000000 }, "expiresAt": null }, "additionalParameters": {} }调用根据ID获取商品接口时加入Token:
GET /goods/234355451 HTTP/1.1 Host: localhost:8080 Authorization: Bearer eyJraWQImFsZyI6IlJTMjU2In0.eyJzdWIiOiJ1NzgsImlhdCI6MTYxNjkxODk3OCwianRpIjoiNThlOTQktNGVlYzc3MDU0ZDk3In0.ZQcN0FX7_taohqPiC1KnoF7本文转载自微信公众号「码农小胖哥」,可以通过以下二维码关注。转载本文请联系码农小胖哥公众号。IT技术网

随机阅读
热门排行
友情链接