Shiro use at the gateway to solve the filter url

      Recently the company's services have such a demand: there are two sets of back-office services in the background when requested, it will start with permissions gateway layer interception. According to the menu owned by the currently logged in user, role, and url address request to intercept can request to another service address. Gateway layer used shiro rights management, has a good package roles, permissions and account number. But it has been thought to understand the issue of interception of uri. Shiro then see the source code from our existing login looks. Finally managed to find a solution

      shiro at login time, login method is the use of the Subject.

  

Subject currentLoginUser = SecurityUtils.getSubject();
		//A:是否已经登录
		if(currentLoginUser.isAuthenticated()) {
			Boolean isAjax = (Boolean) request.getAttribute("X_IS_AJAX");
			if(  isAjax  ) {
				return AjaxResponse.success( null );
			}else {
				response.sendRedirect(homepageUrl);
				return null;
			}
		}
		//B:查询用户信息
		CarAdmUser user = carAdmUserExMapper.queryByAccount(username,null);
		if(user==null){
			return AjaxResponse.fail(RestErrorCode.USER_NOT_EXIST) ;
		}
		//C:密码不正确
		String enc_pwd = PasswordUtil.md5(password, user.getAccount());
		if(!enc_pwd.equalsIgnoreCase(user.getPassword())) {
			AjaxResponse.fail return (RestErrorCode.USER_PASSWORD_WRONG); 
		} 
		
		// E: user state 
		IF (! user.getStatus () = null && user.getStatus () intValue () == 100.) { 
			return AjaxResponse.fail (RestErrorCode.USER_INVALID ); 
		} 
		// F.: performing log 
		the try { 
			// Log Shiro 
			UsernamePasswordToken new new token = UsernamePasswordToken (username, password.toCharArray ()); 			currentLoginUser.login (token);
 			// record all user login session ID to support " system management "function in automatic session cleanup 
			String sessionId = (String) currentLoginUser.getSession () getId ();. 
			redisSessionDAO.saveSessionIdOfLoginUser (username, sessionId); 
			redisTemplate.delete (redis_login_key); 
			redisTemplate.delete (redis_getmsgcode_key);



		}catch(AuthenticationException aex) {
			return AjaxResponse.fail(RestErrorCode.USER_LOGIN_FAILED) ;
		}
		//返回登录成功
		Boolean isAjax = (Boolean) request.getAttribute("X_IS_AJAX");
		if(  isAjax  ) {
			return AjaxResponse.success( null );
		}else {
			response.sendRedirect(homepageUrl);
			return null;
		}

  

currentLoginUser.login (token); shiro is rewritten inside AuthorizingRealm ()
package com.sq.transportmanage.gateway.service.shiro.realm;

import com.sq.transportmanage.gateway.dao.entity.driverspark.CarAdmUser;
import com.sq.transportmanage.gateway.dao.mapper.driverspark.ex.SaasPermissionExMapper;
import com.sq.transportmanage.gateway.dao.mapper.driverspark.ex.SaasRoleExMapper;
import com.sq.transportmanage.gateway.service.auth.MyDataSourceService;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
org.springframework.beans.factory.annotation.Autowired Import;
org.springframework.stereotype.Component Import; 

Import java.util.HashSet; 
Import java.util.List; 
Import java.util.Set; 

/ ** authentication and rights ** / 

/ ** 
 * This is the shiro SSOLogin user acquisition configuration attribute 
 * / 
@Component 
public class UsernamePasswordRealm the extends AuthorizingRealm { 
    Private static Logger Logger = Final LoggerFactory.getLogger (UsernamePasswordRealm.class); 

	@Autowired 
	Private myDataSourceService myDataSourceService; 

	@Autowired 
	Private SaasPermissionExMapper saasPermissionExMapper; 

	@Autowired 
	Private SaasRoleExMapper saasRoleExMapper; 
	
    / ** weight write: obtaining user authentication information ** / 
	@Override
    AuthenticationInfo doGetAuthenticationInfo protected (AuthenticationToken AuthenticationToken) throws of AuthenticationException { 
		logger.info ( "[acquired user authentication information start] AuthenticationToken =" + AuthenticationToken); 
		the try { 
			UsernamePasswordToken token = (UsernamePasswordToken) AuthenticationToken; 
			CarAdmUser admuser = myDataSourceService.queryByAccount (token. getUsername ()); 
			SSOLoginUser loginUser = new new SSOLoginUser (); // user currently logged 
			loginUser.setId (adMUser.getUserId ()); // user ID 
			loginUser.setLoginName (adMUser.getAccount ()); // login 
			loginUser .setMobile (adMUser.getPhone ()); // phone number 
			loginUser.setType (null); // 
			loginUser.setName (adMUser.getUserName ()); // real name
			loginUser.setEmail (adMUser.getEmail ()); // email address 
			loginUser.setStatus (adMUser.getStatus ()); // state 
			loginUser.setAccountType (adMUser.getAccountType ()); // own account type: [100 ordinary users], [900 administrator] 
			loginUser.setLevel (adMUser.getLevel ()); 
			loginUser.setUuid (adMUser.getUuid ()); 

			List <String> menuUrlList = saasPermissionExMapper.queryPermissionCodesOfUser (adMUser.getUserId ()); 
			loginUser. setMenuUrlList (menuUrlList); 

			// ------------------------------------------- -------------------------------------------------- data permission ------------ the BEGIN 

			logger.info ( "[user authentication information acquired] =" + loginUser); 
			return new new SimpleAuthenticationInfo (loginUser, authenticationToken.getCredentials (), this.getName ( )); 
		} the catch (exception E) { 
			logger.error ( "user authentication information acquired abnormal", E); 
			return null; 
		} 
	} 


	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
		SSOLoginUser loginUser = (SSOLoginUser) principalCollection.getPrimaryPrincipal();
		String account = loginUser.getLoginName(); //登录名

		List<String> perms_string = saasPermissionExMapper.queryPermissionCodesOfUser(  loginUser.getId() );
		List<String> roles_string   = saasRoleExMapper.queryRoleCodesOfUser( loginUser.getId() );

		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		Set<String> roles = new HashSet<String>( roles_string );
		authorizationInfo.setRoles( roles );
		logger.info ( "[obtaining user authorization information (role)]" + Account + "=" + Roles); 

		Set<String> perms = new HashSet<String>( perms_string );
		authorizationInfo.setStringPermissions(perms);
		logger.info ( "[obtaining user authorization information (permission)]" + Account + "=" + PERMS); 
		return authorizationInfo ; 
	} 

	@Override 
    public Object getAuthorizationCacheKey (PrincipalCollection Principals) { 
		SSOLoginUser loginUser = (SSOLoginUser) principals.getPrimaryPrincipal (); 
		String Account = loginUser.getLoginName (); // login 
        return "-AuthInfo -" + Account; 
    } 
	

    @Override 
    public clearCachedAuthorizationInfo void (PrincipalCollection Principals) { 
        super.clearCachedAuthorizationInfo (Principals);
    }
    @Override
    public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
        super.clearCachedAuthenticationInfo(principals);
    }
    @Override
    public void clearCache(PrincipalCollection principals) {
        super.clearCache(principals);
    }
}

  This can be through the login information into shiro inside, the following menu is specific permissions. Normally, use the comments shiro

@RequiresPermissions (value = { "value" }) 
can be used normally. @RequiresPermissions source which is used aop way, by determining whether the value of a set value which determines whether there is authority (Reference: https://blog.csdn.net/xiewenfeng520/article/details/89447749 )
. But our project is somewhat different, this is the gateway layer, the authority is doing to configure the gateway, and then determine whether to jump to the specified url. I have thought a good day how to intercept the url, because the parameters of my table relationships inside a url address will not pass. Then after reading the source code to achieve shiro,
I found myself thinking no problem, but the url will pass. So plan changed this:

1) write an interceptor to intercept url address
2) Once logged in, the menu will contain the user's permission to put shiro inside
3) interceptor inside judgment, if the administrator directly through, if not to see whether the user has the permission.
Specific implementation code:
. 1) Zuul blockers:
package com.sq.transportmanage.gateway.api.web.filter;

import com.alibaba.fastjson.JSONObject;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.sq.transportmanage.gateway.api.common.AuthEnum;
import com.sq.transportmanage.gateway.service.shiro.realm.SSOLoginUser;
import com.sq.transportmanage.gateway.service.shiro.session.WebSessionUtil;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

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

/**
 * @program: sq-union-manage
 * @description: AccessFilter
 * @author: zjw
 * @create: 2020-02-23 18:57
 **/
@Component
@RequiresPermissions("/")
public class AccessFilter extends ZuulFilter {

    private static Logger logger = LoggerFactory.getLogger(AccessFilter.class);

    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 1;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {

        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        logger.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
        SSOLoginUser loginUser = WebSessionUtil.getCurrentLoginUser();
        logger.info(String.format("%s loginUser %s", loginUser.getLoginName(), loginUser.getName()));
        /**用户是否有权限**/
        boolean bl = false;
        //如果是管理员 直接通过
        if(AuthEnum.MANAGE.getAuthId().equals(loginUser.getAccountType())){
            bl = true;
        }else {
            String uri = request.getRequestURI().toString();
            List <String> menuUrl loginUser.getMenuUrlList = (); 
            IF (menuUrl.contains (URI)) {
                bl = true;
            }
        } 
        IF (BL) { 
            ctx.addZuulRequestHeader ( "user_token", JSONObject.toJSONString (loginUser)); 
        } the else { 
            ctx.setSendZuulResponse (to false); // filtering the request, without routing it 
            ctx.setResponseStatusCode (401); / / error code is returned 
            ctx.setResponseBody ( "{\" code \ ": 0, \" result \ ": \" authentication failed authentication gateway 2 \! "}"); // returns the contents of the error 
            ctx.set ( " isSuccess ", to false); 
        } 

        // increase the TODO permission determination herein can 
        return CTX; 
    } 

}

  2) shiro storage rights:

 

package com.sq.transportmanage.gateway.service.shiro.realm;

import com.sq.transportmanage.gateway.dao.entity.driverspark.CarAdmUser;
import com.sq.transportmanage.gateway.dao.mapper.driverspark.ex.SaasPermissionExMapper;
import com.sq.transportmanage.gateway.dao.mapper.driverspark.ex.SaasRoleExMapper;
import com.sq.transportmanage.gateway.service.auth.MyDataSourceService;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
org.springframework.beans.factory.annotation.Autowired Import; 
Import org.springframework.stereotype.Component; 

Import java.util.HashSet; 
Import java.util.List; 
Import java.util.Set; 

/ * * * authentication and rights * / 

/ * * 
 * this is obtained shiro SSOLogin user configuration attributes 
 * / 
@Component 
public  class UsernamePasswordRealm the extends AuthorizingRealm {
     Private  static Final Logger Logger = LoggerFactory.getLogger (UsernamePasswordRealm. class ); 

    @Autowired 
    Private myDataSourceService myDataSourceService; 

    @Autowired 
    PrivateSaasPermissionExMapper SaasPermissionExMapper; 

    @Autowired 
    Private SaasRoleExMapper saasRoleExMapper; 
    
    / * * rewritten: obtaining user authentication information * * / 
    @Override 
    protected AuthenticationInfo doGetAuthenticationInfo (AuthenticationToken AuthenticationToken) throws of AuthenticationException { 
        logger.info ( " [acquired user authentication information start] = AuthenticationToken " + AuthenticationToken);
         the try { 
            UsernamePasswordToken token = (UsernamePasswordToken) AuthenticationToken; 
            CarAdmUser admuser = new new myDataSourceService.queryByAccount (token.getUsername ());
            LoginUser SSOLoginUser =SSOLoginUser ();   // currently logged on user 
            loginUser.setId (adMUser.getUserId ());                 // user ID 
            loginUser.setLoginName (adMUser.getAccount ()); // login 
            loginUser.setMobile (adMUser.getPhone ()) ;          // phone number 
            loginUser.setName (adMUser.getUserName ());     // real name 
            loginUser.setEmail (adMUser.getEmail ()); // mail address 
            loginUser.setType ( null );    //
             loginUser.setStatus (admuser. the getStatus ());            // state 
            loginUser.setAccountType (adMUser.getAccountType ());    // own account type: [100 ordinary users], [900 Administrator] 
            loginUser.setLevel (adMUser.getLevel ()); 
            loginUser.setUuid (adMUser.getUuid ( )); 

            List <String> menuUrlList = saasPermissionExMapper.queryPermissionCodesOfUser (adMUser.getUserId ()); 
            loginUser.setMenuUrlList (menuUrlList); 

            // --------------------- -------------------------------------------------- ---------------------------------- data permission BEGIN 

            logger.info ( " [to obtain user authentication information] = " + loginUser);
             return  new newSimpleAuthenticationInfo (loginUser, authenticationToken.getCredentials (),   the this .getName ()); 
        } the catch (Exception E) { 
            logger.error ( " acquired user authentication information abnormal " , E);
             return  null ; 
        } 
    } 


    @Override 
    protected AuthorizationInfo doGetAuthorizationInfo (principalCollection principalCollection) { 
        SSOLoginUser loginUser = (SSOLoginUser) principalCollection.getPrimaryPrincipal (); 
        String the Account = loginUser.getLoginName (); // login 

        List<String> perms_string = saasPermissionExMapper.queryPermissionCodesOfUser(  loginUser.getId() );
        List<String> roles_string   = saasRoleExMapper.queryRoleCodesOfUser( loginUser.getId() );

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        Set<String> roles = new HashSet<String>( roles_string );
        authorizationInfo.setRoles( roles );
        logger.info( "[获取用户授权信息(角色)] "+account+"="+roles);

        Set<String> perms = new HashSet<String>( perms_string );
        authorizationInfo.setStringPermissions(perms);
        logger.info( "[获取用户授权信息(权限)] "+account+"="+perms);
        return authorizationInfo;
    }

    @Override
    public Object getAuthorizationCacheKey(PrincipalCollection principals) {
        SSOLoginUser loginUser = (SSOLoginUser) principals.getPrimaryPrincipal();
        String account = loginUser.getLoginName(); //登录名
        return "-AuthInfo-"+account;
    }
    

    @Override
    public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
        super.clearCachedAuthorizationInfo(principals);
    }
    @Override
    public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
        super.clearCachedAuthenticationInfo(principals);
    }
    @Override
    public void clearCache(PrincipalCollection principals) {
        super.clearCache(principals);
    }
}

Probably idea is this. . .

Guess you like

Origin www.cnblogs.com/thinkingandworkinghard/p/12375502.html