/** 
 | 
 * Copyright (c) 2018 人人开源 All rights reserved. 
 | 
 * 
 | 
 * https://www.renren.io 
 | 
 * 
 | 
 * 版权所有,侵权必究! 
 | 
 */ 
 | 
  
 | 
package com.zt.core.shiro; 
 | 
  
 | 
import com.alibaba.fastjson.JSONObject; 
 | 
import com.zt.common.exception.ErrorCode; 
 | 
import com.zt.common.utils.MessageUtils; 
 | 
import com.zt.core.context.User; 
 | 
import com.zt.modules.sys.enums.UserStatus; 
 | 
import com.zt.security.model.SysUserToken; 
 | 
import com.zt.security.service.ShiroService; 
 | 
import org.apache.shiro.authc.*; 
 | 
import org.apache.shiro.authz.AuthorizationInfo; 
 | 
import org.apache.shiro.authz.SimpleAuthorizationInfo; 
 | 
import org.apache.shiro.realm.AuthorizingRealm; 
 | 
import org.apache.shiro.subject.PrincipalCollection; 
 | 
import org.springframework.beans.factory.annotation.Autowired; 
 | 
import org.springframework.beans.factory.annotation.Value; 
 | 
import org.springframework.context.annotation.Lazy; 
 | 
import org.springframework.data.redis.core.RedisTemplate; 
 | 
import org.springframework.stereotype.Component; 
 | 
  
 | 
import java.util.Date; 
 | 
import java.util.List; 
 | 
  
 | 
/** 
 | 
 * 认证 
 | 
 * 
 | 
 * @author Mark sunlightcs@gmail.com 
 | 
 */ 
 | 
@Component 
 | 
public class Oauth2Realm extends AuthorizingRealm { 
 | 
  
 | 
    @Lazy 
 | 
    @Autowired 
 | 
    private ShiroService shiroService; 
 | 
    @Autowired 
 | 
    private RedisTemplate redisTemplate; 
 | 
  
 | 
    @Value("${spring.cache.type}") 
 | 
    private String type; 
 | 
    @Value("${data.tokenTimeout}") 
 | 
    private Long tokenTimeout; 
 | 
  
 | 
    @Override 
 | 
    public boolean supports(AuthenticationToken token) { 
 | 
        return token instanceof Oauth2Token; 
 | 
    } 
 | 
    /** 
 | 
     * 授权(验证权限时调用) 
 | 
     */ 
 | 
    @Override 
 | 
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { 
 | 
        User user = (User) principals.getPrimaryPrincipal(); 
 | 
  
 | 
        // 用户权限列表 
 | 
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); 
 | 
        info.setStringPermissions(user.getPermissions()); 
 | 
        return info; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 认证(登录时调用) 
 | 
     */ 
 | 
    @Override 
 | 
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { 
 | 
        String accessToken = (String) token.getPrincipal(); 
 | 
  
 | 
        // 根据accessToken,查询用户信息 
 | 
        SysUserToken tokenEntity; 
 | 
        if (!"redis".equals(type)){ 
 | 
            tokenEntity = shiroService.getByToken(accessToken); 
 | 
        } 
 | 
        else{ 
 | 
            String json = (String)redisTemplate.opsForValue().get(accessToken); 
 | 
            tokenEntity = JSONObject.parseObject(json, SysUserToken.class); 
 | 
            //User user = tokenEntity.getUser(); 
 | 
            //List<Long> roleIdList = user.getRoleIdList(); 
 | 
        } 
 | 
        // token失效 
 | 
        if (tokenEntity == null || tokenEntity.getExpireDate().getTime() < System.currentTimeMillis()) { 
 | 
            throw new IncorrectCredentialsException(MessageUtils.getMessage(ErrorCode.TOKEN_INVALID.getCode())); 
 | 
        } 
 | 
  
 | 
        // 当前时间 
 | 
        Date now = new Date(); 
 | 
        // 过期时间 
 | 
        Date expireTime = new Date(now.getTime() + tokenTimeout * 60 * 1000); 
 | 
        tokenEntity.setUpdateDate(now); 
 | 
        tokenEntity.setExpireDate(expireTime); 
 | 
        if ("redis".equals(type)) { 
 | 
            String jsonString = JSONObject.toJSONString(tokenEntity); 
 | 
            redisTemplate.opsForValue().set(token, jsonString); 
 | 
        }else{ 
 | 
            this.shiroService.updateTokenById(tokenEntity); 
 | 
        } 
 | 
  
 | 
        // 查询用户信息 
 | 
        User user = shiroService.getUser(tokenEntity.getUserId()); 
 | 
        user.setSystemMarker(tokenEntity.getSystemMarker()); 
 | 
        user.setRoleName(tokenEntity.getRoleName()); 
 | 
  
 | 
        // 账号锁定 
 | 
        if (user.getStatus() == UserStatus.DISABLE.getValue()) { 
 | 
            throw new LockedAccountException(MessageUtils.getMessage(ErrorCode.ACCOUNT_LOCK.getCode())); 
 | 
        } 
 | 
  
 | 
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, accessToken, getName()); 
 | 
        return info; 
 | 
    } 
 | 
  
 | 
} 
 |