栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

EasyShiro-可用于分布式应用的鉴权工具

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

EasyShiro-可用于分布式应用的鉴权工具

EasyShiro(最后有例子下载)

文章目录

EasyShiro(最后有例子下载)

特色

1/简单易用2/轻装上阵3/ 保留session功能并兼顾性能4/兼容session、jwt和单纯的token访问5/提供SessionUtils工具 应用

1/加入依赖2/写一个MyAuthenticationInfoService的实现,这里只是为了演示,直接将帐户权限数据放在accounts变量里,实际应用时一般来自数据库3/写一个controller接受登录和授权测试4/在application启动类加入"com.freestyle.easyshiro.web"的扫描 postman测试cache对于shiro的重要性例子下载

特色 1/简单易用

几乎开箱即用,不用写冗余繁琐的代码。
登录后储存在Principal的为内置的UserDtoWithPermission,它是AuthenticationWithPermission的实现,包含如下信息:
account/roles/permissions

2/轻装上阵

没有集成数据库,AbstractAccountRealm留有接口可以自行实现login(身份认证)和getAuthorization(获取授权),所以你可以用mysql,postgresql或memory任何一种方式来管理帐户、授权认证

3/ 保留session功能并兼顾性能

重写session dao,后端用J2Cache实现,并对其加入了增强的jackson序列化功能,j2cache的序列化配置默认用jackson,这个才能更好应对shiro的session在redis的存取。而由于用了j2Cache(一级缓存用caffeine,二级缓存用redis),默认通知机制用了rabbitmq,具体配置请查阅包内j2cache.properties。所以你也可以通过自行配置j2cache.properties和caffeine.properties来进行更细节的参数调整
easyshiro保留session管理,并用j2cache进行缓存,兼容jwt token和session token,具体能数配置放在easy-shiro.yml

easy-shiro:
  session-time-out: 1800
  cache-enabled: true
  allow-cross-domain: true
  sessionIdUrlRewritingEnabled: false
  #如果配置sessionTokenName,则会从request的header的#sessionTokenName里面取这个token从而可以不用传递cookie
  session-token-name: token
  #如果配置jwtTokenName,则会从request的header的#jwtTokenName里面取jwt令牌并验证其有效性并从中取出token
  #优先顺序: cookie->session token -> jwt token
  jwt-token-name: access-token
  session-region: my-easy-shiro-web-sample
  redirect:
      "login": "/user/login"
      "401": "/user/login"
4/兼容session、jwt和单纯的token访问

  因为eashshiro用j2cache管理session,所以性能不是问题, 通过配置easy-shiro.yml登录后自行返回jwt token和token,之后的访问携带三者任何一样作为鉴权依据即可。

5/提供SessionUtils工具

可直接根据sessionid拿到Subject,便于在非web容器的应用(如netty或其他iot环境)进行认证和鉴权

Serializable sessionId=getSessionIdFrom ...
      SessionUtils sessionUtils=new SessionUtils(shiroConfig.getSecurityManager(),
              (DefaultSessionManager) ((DefaultSecurityManager)shiroConfig.getSecurityManager()).getSessionManager());
      Subject subject=sessionUtils.createSubject(sessionId);
      Assert.assertNotNull(subject);
      subject.checkPermission("P3"); //检查授权
      ...
应用

基本上开箱即用,包里默认自带filter-chain-map.json,如果你有需要就在自己的项目里面新建一个覆盖它:

{
  "/user/login": "anon",
  "/swagger-ui.html": "anon",
  "/swagger-resources/**": "anon",
  "/v2/api-docs": "anon",
  "/css/**": "anon",
  "/js/**": "anon",
  "/fonts/**": "anon",
  "/img/**": "anon",
  "/**": "myauthc,crossDomain"
}

easyshiro默认用到rabbitmq和redis,它们的默认配置如下,如果有需要修改的请覆盖j2cache.properties

# RabbitMQ properties
rabbitmq.exchange = j2cache
rabbitmq.host = localhost
rabbitmq.port = 5672
rabbitmq.username = root
rabbitmq.password = 123456
rabbitmq.virtualHost = /

redis.hosts = 127.0.0.1:6379
redis.timeout = 2000
redis.password =12345678
redis.database = 0
redis.ssl = false

1/加入依赖

        
            sonatype-nexus-snapshots
            Sonatype Nexus Snapshots
            https://s01.oss.sonatype.org/content/repositories/snapshots/
            
                false
            
            
                true
            
        
    

            io.github.tiger822
            easy-shiro-web
            1.0-SNAPSHOT
        

        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.boot
            spring-boot-starter-aop
        


        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
2/写一个MyAuthenticationInfoService的实现,这里只是为了演示,直接将帐户权限数据放在accounts变量里,实际应用时一般来自数据库
@Service
public class MyAuthenticationInfoServiceImpl implements MyAuthenticationInfoService {
  private Map accounts=new HashMap<>();
  public MyAuthenticationInfoServiceImpl() {
    accounts.put("user1",new MyAuthenticationInfo(new UserDtoWithPermission("user1",new HashSet(){{add("ROLE1");add("ROLE2");}},
            new HashSet(){{add("P1");}}),"123456","accountRealm"));
    accounts.put("user2",new MyAuthenticationInfo(new UserDtoWithPermission("user2",new HashSet(){{add("ROLE1");add("ROLE2");}},
            new HashSet(){{add("P1");add("P2");}}),"123456","accountRealm"));
  }

  @Override
  public MyAuthenticationInfo login(UsernamePasswordToken token) {
    return accounts.get(token.getUsername());
  }

  @Override
  public AuthorizationInfo getAuthorization(UserDtoWithPermission principal) {
    return principal;
  }
}
3/写一个controller接受登录和授权测试
@RestController
@RequestMapping("/user")
public class LoginController {
  @Resource
  private WebSessionEasyShiroProperties properties;
  @Resource
  private WebSessionAbleEasyShiroConfig shiroConfig;
  @GetMapping("login")
  public Object login(@RequestParam(value = "user",required = false)String user, @RequestParam(value = "password",required = false) String password, HttpServletResponse response){
    if (user==null){
      return "显示登录界面";
    }
    Subject subject = SecurityUtils.getSubject(); // 获取当前主体
    UsernamePasswordToken token = new UsernamePasswordToken(user, password);
    try {
      subject.login(token); // 登录
      if (!StringUtils.isBlank(properties.getSessionTokenName())){
        response.setHeader(properties.getSessionTokenName(), subject.getSession().getId().toString());
      }
      if (!StringUtils.isBlank(properties.getJwtTokenName())){
        String jwtToken= JwtUtils.getToken(subject.getSession().getId(),properties.getSessionTimeOut(), TimeUnit.SECONDS);
        //返回两组token,之后的访问随便用哪个
        response.setHeader(properties.getJwtTokenName(), jwtToken);
      }

      return ResponseEntity.fromResult(0,"OK");
    }
    catch (UnknownAccountException |IncorrectCredentialsException e){
      return ResponseEntity.fromErr(0,-1,"用户或密码无效");
    }
  }
  @GetMapping("subject")
  @RequiresPermissions(logical = Logical.AND, value = {"p1"})
  public Object getSubject(HttpServletRequest request) throws JsonProcessingException {
    Subject subject=shiroConfig.getSessionUtils().createSubject(request.getHeader("token"));
    UserDtoWithPermission userDtoWithPermission=(UserDtoWithPermission)subject.getPrincipal();
    Map values=new HashMap<>();
    values.put("account",userDtoWithPermission.getAccount() );
    values.put("roles",userDtoWithPermission.getRoles());
    values.put("permissions",userDtoWithPermission.getPermissions());
    return ResponseEntity.fromResult(0,values);
  }
  @GetMapping("p1")
  @RequiresPermissions(logical = Logical.AND, value = {"p1"})
  public Object p1(){
    return ResponseEntity.fromResult(0,"权限通过,返回P1");
  }
  @GetMapping("p2")
  @RequiresPermissions(logical = Logical.AND, value = {"p2"})
  public Object p2(){
    return ResponseEntity.fromResult(0,"权限通过,返回P2");
  }
}
4/在application启动类加入"com.freestyle.easyshiro.web"的扫描
@SpringBootApplication(scanbasePackages = {"com.freestyle.easyshiro","com.freestyle.easyshiro.web"})
@EnableAspectJAutoProxy(proxyTargetClass=true,exposeProxy = true)
public class Application {
  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}

postman测试

get http://localhost:8080/user/login?user=user1&password=123456
返回结果除了cookie还返回了access-token和token。登录后,redis后台便有了session数据,只要不同的服务同样用了easyshiro这套鉴权工具,后面的请求随便用哪个作为令牌对任何一组服务进行访问即可。

通过携带cookie进行访问:

通过携带token进行访问:

通过携带jwt的access token进行访问:

cache对于shiro的重要性

shiro对session的访问次数一点也不严谨,一次请求中它会频繁访问session(19次读,1次更新),如下图,所以1级缓冲用上高性能的caffeine最好不过了,命中率非常高,而2级缓存用redis,则可满足一处登录到处使用的需求。

09:33:02.990 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - doReadSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.990 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - doReadSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.990 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - doReadSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.990 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - doReadSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.990 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - doReadSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.990 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - doReadSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.990 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - doReadSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.991 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - doReadSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.991 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - doReadSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.991 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - doReadSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.991 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - doReadSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.991 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - update session ,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.991 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - storeSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.995 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - doReadSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.995 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - doReadSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.996 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - doReadSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.996 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - doReadSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.996 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - doReadSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.997 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - doReadSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.997 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - doReadSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f
09:33:02.999 [http-nio-8080-exec-7] DEBUG com.freestyle.easyshiro.web.J2CacheSessionDAO - doReadSession,session id:7714603b-2ed1-4b2f-a804-2f0178ad4e2f

例子下载

https://download.csdn.net/download/rocklee/84986491

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/769950.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号