フィルタのURLを解決するためのゲートウェイで史郎使用

      最近、同社のサービスは、このような要望を持っている:要求し、それは権限ゲートウェイ層の傍受を開始する時期のバックオフィスサービスの二組は、バックグラウンドです。現在切片へのユーザー、役割、およびURLアドレス要求ログインが所有しているメニューによると、別のサービス・アドレスに要求することができます。史郎権管理に使用ゲートウェイ層は、優れたパッケージの役割、権限と口座番号を持っています。しかし、URIの傍受の問題を理解するために考えられてきました。史郎は、当社の既存のログインルックスからソースコードを参照してください。最後に解決策を見つけることができました

      ログイン時史郎は、ログイン方法は、対象の使用です。

  

被験者currentLoginUser = SecurityUtils.getSubject()。
		// A:是否已经登录
		IF(currentLoginUser.isAuthenticated()){ 
			ブールisAjax =(ブール)request.getAttribute( "X_IS_AJAX")。
			(isAjax){もし
				リターンAjaxResponse.success(NULL)。
			}他{ 
				response.sendRedirect(homepageUrl)。
				ヌルを返します。
			} 
		} 
		// B:查询用户信息
		CarAdmUserユーザー= carAdmUserExMapper.queryByAccount(ユーザ名、NULL); 
		IF(ユーザ== NULL){ 
			リターンAjaxResponse.fail(RestErrorCode.USER_NOT_EXIST)。
		} 
		// C:密码不正确
		ストリングenc_pwd = PasswordUtil.md5(パスワード、user.getAccount())。
		(もし!enc_pwd.equalsIgnoreCase(user.getPassword())){
			AjaxResponse.failリターン(RestErrorCode.USER_PASSWORD_WRONG); 
		} 
		
		// E:ユーザ状態
		IF(!user.getStatus()= NULL && user.getStatus()intValue()== 100){ 
			リターンAjaxResponse.fail(RestErrorCode.USER_INVALID ); 
		} 
		// F:ログインを行う
		{試し
			//ログイン史郎
			UsernamePasswordToken新しい新しいトークン= UsernamePasswordToken(ユーザ名、password.toCharArray()); 			)currentLoginUser.login(トークン;
 			//サポートするすべてのユーザーのログインセッションIDを記録します"自動セッション・クリーンアップのシステム管理「機能
			文字列セッションID =(文字列)currentLoginUser.getSession()のgetId();. 
			redisSessionDAO.saveSessionIdOfLoginUser(ユーザ名、セッションID); 
			redisTemplate.delete(redis_login_key); 
			redisTemplate.delete(redis_getmsgcode_key)。



		}キャッチ(含むAuthenticationException AEX){ 
			リターンAjaxResponse.fail(RestErrorCode.USER_LOGIN_FAILED)。
		} 
		//返回登录成功
		ブールisAjax =(ブール)request.getAttribute( "X_IS_AJAX")。
		(isAjax){もし
			リターンAjaxResponse.success(NULL)。
		}他{ 
			response.sendRedirect(homepageUrl)。
			ヌルを返します。
		}

  

currentLoginUser.login(トークン);しろ)は(AuthorizingRealm内部に書き換えられます
パッケージcom.sq.transportmanage.gateway.service.shiro.realm。

輸入com.sq.transportmanage.gateway.dao.entity.driverspark.CarAdmUser; 
輸入com.sq.transportmanage.gateway.dao.mapper.driverspark.ex.SaasPermissionExMapper; 
輸入com.sq.transportmanage.gateway.dao.mapper.driverspark.ex.SaasRoleExMapper; 
輸入com.sq.transportmanage.gateway.service.auth.MyDataSourceService。
輸入org.apache.shiro.authc *。; 
輸入org.apache.shiro.authz.AuthorizationInfo; 
輸入org.apache.shiro.authz.SimpleAuthorizationInfo; 
輸入org.apache.shiro.realm.AuthorizingRealm; 
輸入org.apache.shiro.subject.PrincipalCollection。
輸入org.slf4j.Logger; 
輸入org.slf4j.LoggerFactory。
輸入org.springframework.beans.factory.annotation.Autowired;
org.springframework.stereotype.Componentインポート、

インポートはjava.util.HashSet; 
インポートはjava.util.List; 
インポートjava.util.Set; 

/ **認証及び権利** / 

/ ** 
 *これは、史郎SSOLoginユーザー獲得ですコンフィギュレーション属性
 * / 
@Component 
パブリッククラスUsernamePasswordRealm AuthorizingRealm {延び
    プライベート静的ロガーロガー=最終LoggerFactory.getLogger(UsernamePasswordRealm.class); 

	@Autowired 
	プライベートmyDataSourceService myDataSourceService; 

	@Autowired 
	プライベートsaasPermissionExMapper saasPermissionExMapper; 

	@Autowired 
	プライベートsaasRoleExMapper saasRoleExMapper; 
	
    / **重量書き込み:取得ユーザ認証情報** / 
	@Override
    AuthenticationInfo doGetAuthenticationInfoは(AuthenticationToken AuthenticationToken)を保護含むAuthenticationException {からスロー
		logger.info( "[取得したユーザ認証情報スタート] AuthenticationToken =" + AuthenticationToken); 
		試み{ 
			UsernamePasswordTokenトークン=(UsernamePasswordToken)AuthenticationToken; 
			CarAdmUser必ずadmuser = myDataSourceService.queryByAccount(トークン。 getUsername()); 
			SSOLoginUser loginUser =新新SSOLoginUser(); //ユーザーが現在ログインし
			loginUser.setId(adMUser.getUserIdを()); //ユーザーID 
			loginUser.setLoginName(adMUser.getAccount()); //ログイン
			loginUser .setMobile(adMUser.getPhone()); //電話番号 
			loginUser.setType(NULL); // 
			loginUser.setName(adMUser.getUserName()); //実際の名前
			loginUser.setEmail(adMUser.getEmail()); //メールアドレス
			loginUser.setStatus(adMUser.getStatus()); //状態
			loginUser.setAccountType(adMUser.getAccountType()); //独自のアカウントの種類:[100通常のユーザー]、[900アドミニストレータ] 
			loginUser.setLevel(adMUser.getLevel()); 
			loginUser.setUuid(adMUser.getUuid()); 

			リストの<string> menuUrlList = saasPermissionExMapper.queryPermissionCodesOfUser(adMUser.getUserId()); 
			loginUser。 setMenuUrlList(menuUrlList); 

			// ------------------------------------------- --------------------------------------------------データ許可------------ BEGIN 

			logger.info( "= [ユーザ認証情報が取得された" + loginUserを); 
			戻り新しい新しいSimpleAuthenticationInfo(loginUser、authenticationToken.getCredentials()、this.getName( ));
		}キャッチ(例外e){ 
			logger.error( "获取用户的身份认证信息异常"、E)。
			ヌルを返します。
		} 
	} 

 
	@Override
	AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection){保護
		SSOLoginUser loginUser =(SSOLoginUser)principalCollection.getPrimaryPrincipalは(); 
		文字列のアカウント= loginUser.getLoginName(); //登录名

		一覧<文字列> perms_string = saasPermissionExMapper.queryPermissionCodesOfUser(loginUser.getId()); 
		一覧<文字列> roles_string = saasRoleExMapper.queryRoleCodesOfUser(loginUser.getId()); 

		SimpleAuthorizationInfo authorizationInfo =新しいSimpleAuthorizationInfo(); 
		セット<文字列>の役割=新しいHashSetの<文字列>(roles_string)。
		authorizationInfo。
		logger.info( "[获取用户授权信息(角色)] "+アカウント+"=" +役割)。

		セット<文字列>パーマ=新しいHashSetの<文字列>(perms_string)。
		authorizationInfo。
		logger.info( "[获取用户授权信息(权限)] "+アカウント+"=" +パーマ)。
		authorizationInfoを返します。
	} 

	@Override 
    パブリックオブジェクトgetAuthorizationCacheKey(PrincipalCollectionプリンシパル){ 
		SSOLoginUser loginUser =(SSOLoginUser)principals.getPrimaryPrincipal(); 
		文字列のアカウント= loginUser.getLoginName(); //登录名
        の戻り"-AuthInfo - " +アカウント。
    } 
	

    @Override 
    公共ボイドclearCachedAuthorizationInfo(PrincipalCollectionプリンシパル){ 
        super.clearCachedAuthorizationInfo(プリンシパル)。
    } 
    @Override  
    公共ボイドclearCachedAuthenticationInfo(PrincipalCollectionプリンシパル){
        super.clearCachedAuthenticationInfo(プリンシパル)。
    } 
    @Override
    公共ボイドclearCache(PrincipalCollectionプリンシパル){ 
        super.clearCache(プリンシパル)。
    } 
}

  これは、次のメニューは、特定の権限で、史郎の内部へのログイン情報を介して行うことができます。通常、コメント史郎を使用

@RequiresPermissions(値= { "値" }) 
正常に使用することができます。決定することによって、AOP方法で使用される@RequiresPermissions源か権限があるか否かを判断する設定値の値(参照:https://blog.csdn.net/xiewenfeng520/article/details/89447749
しかし、私たちのプロジェクトは、当局がゲートウェイを設定して、指定したURLにジャンプするかどうかを判断するためにやっている、これはゲートウェイ層であり、多少異なります。私は、URLアドレス内の私のテーブル関係のパラメータが渡されないので、URLを傍受するためにどのように良い一日と思っています。そして、史郎を達成するためのソースコードを読んだ後、
私は自分自身が問題を考えていない見つけましたが、URLが渡されます。:この変更計画はそう

インターセプトURLアドレスへの迎撃書き込み)1を
ログインすると、メニューが内側史郎を置くためにユーザーの許可が含まれます)2を
、管理者が直接通じ場合、判断内部インターセプタ)3を、そうでない場合はユーザーが権限を持っているかどうかを確認します。
特定の実装コード:
1)Zuulブロッカー:
パッケージcom.sq.transportmanage.gateway.api.web.filter。

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

インポートのjavax.servlet.http.HttpServletRequest; 
輸入はjava.util.List; 

/ ** 
 * @program:SQ-組合管理 
 * @description:AccessFilter
 * @author:ZJW 
 * @Create:2020年2月23日夜06時57 
 ** / 
@Component 
@RequiresPermissions( "/")
パブリッククラスAccessFilterはZuulFilter {延び

    プライベート静的ロガーロガー= LoggerFactory.getLogger(AccessFilter.class)を、

    @Override 
    パブリック文字列のfilterType(){ 
        戻り「プレ」。
    } 

    @Override 
    公共INT filterOrder(){ 
        1を返します。
    } 

    @Override 
    パブリックブールshouldFilter(){ 
        trueを返します。
    } 

    @Override 
    パブリックオブジェクトラン(){

        RequestContextのCTX = RequestContext.getCurrentContext()。 
            文字列URI = request.getRequestURI()のtoString()。
        HttpServletRequestのリクエスト= ctx.getRequest()。
        logger.info(String.Formatの( "%sの%sの要求"、request.getMethod()、request.getRequestURL()のtoString())); 
        SSOLoginUser loginUser = WebSessionUtil.getCurrentLoginUser()。
        logger.info(String.Formatの( "%sのloginUser%s"は、loginUser.getLoginName()、loginUser.getName()))。
        / **用户是否有权限** / 
        ブールBL =偽; 
        //如果是管理员直接通过
        IF(AuthEnum.MANAGE.getAuthId()に等しい(loginUser.getAccountType())){ 
            BL = TRUE。
        }他{ 
            リストの<string>メニューURL = loginUser.getMenuUrlList()。
            IF(menuUrl.contains(URI)){ 
                BL = TRUE。
            } 
        } 
        IF(BL){ 
            ctx.addZuulRequestHeader( "user_token"、JSONObject.toJSONString(loginUser)); 
        }他{ 
            ctx.setSendZuulResponse (偽); //要求をフィルタリング、それをルーティングせず
            ctx.setResponseStatusCode(401); //戻りエラーコード
            ctx.setResponseBody( "{\"コード\ ":0、\" \結果":\" 認証ゲートウェイ!失敗した認証モードが2である\ "}"); //は、エラー内容を返す
            ctx.set( "isSuccess"、偽の); 
        } 

        // TODOここに増加する権利判断
        戻りCTXを; 
    } 

}

  2)史郎ストレージ権:

 

パッケージcom.sq.transportmanage.gateway.service.shiro.realm。

輸入com.sq.transportmanage.gateway.dao.entity.driverspark.CarAdmUser; 
輸入com.sq.transportmanage.gateway.dao.mapper.driverspark.ex.SaasPermissionExMapper; 
輸入com.sq.transportmanage.gateway.dao.mapper.driverspark.ex.SaasRoleExMapper; 
輸入com.sq.transportmanage.gateway.service.auth.MyDataSourceService。
org.apache.shiro.authcインポートします。* ; 
輸入org.apache.shiro.authz.AuthorizationInfo; 
輸入org.apache.shiro.authz.SimpleAuthorizationInfo; 
輸入org.apache.shiro.realm.AuthorizingRealm; 
輸入org.apache.shiro.subject.PrincipalCollection。
輸入org.slf4j.Logger; 
輸入org.slf4j.LoggerFactory。
org.springframework.beans.factory.annotation.Autowiredインポート、
インポートorg.springframework.stereotype.Component; 

インポートはjava.util.HashSet; 
インポートはjava.util.List; 
インポートjava.util.Set; 

/ * * *認証と権限* / 

/ * * 
 *この得られたシロのSSOLoginユーザ設定属性
 * / 
@Component 
パブリック クラスAuthorizingRealm {延びUsernamePasswordRealm
     プライベート 静的最終ロガーロガー= LoggerFactory.getLogger(UsernamePasswordRealm。クラス); 

    @Autowired 
    プライベートmyDataSourceService myDataSourceServiceと、

    @Autowired 
    プライベートSaasPermissionExMapper SaasPermissionExMapper; 

    @Autowired 
    プライベートSaasRoleExMapper saasRoleExMapper; 
    
    / * *書き換え:取得ユーザ認証情報* * / 
    @Overrideは
    保護AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken AuthenticationToken)を含むAuthenticationException {からスロー
        logger.info([取得したユーザ認証情報スタート] = AuthenticationToken " + AuthenticationToken);
         試み{ 
            UsernamePasswordTokenトークン = (UsernamePasswordToken)AuthenticationToken; 
            CarAdmUser必ずadmuser =新しい新 myDataSourceService.queryByAccount(token.getUsername())。
            LoginUser SSOLoginUser = SSOLoginUser();   // 現在ログオンしているユーザー 
            loginUser.setId(adMUser.getUserId());                 // ユーザID 
            loginUser.setLoginName(adMUser.getAccount()); // ログイン 
            loginUser.setMobile(adMUser.getPhone ());          // 電話番号 
            loginUser.setName(adMUser.getUserName());     // 本名 
            loginUser.setEmail(adMUser.getEmail()); // メールアドレス 
            loginUser.setType(ヌル);    //
             loginUser.setStatus (adMUser.getStatus());            //状態 
            loginUser.setAccountType(adMUser.getAccountType());    // 独自のアカウントの種類:[100の普通のユーザー]、[900管理者] 
            loginUser.setLevel(adMUser.getLevel()); 
            loginUser.setUuid(adMUser.getUuid( )); 

            リストの<string> menuUrlList = saasPermissionExMapper.queryPermissionCodesOfUser(adMUser.getUserId()); 
            loginUser.setMenuUrlList(menuUrlList); 

            // --------------------- -------------------------------------------------- ----------------------------------データ許可はBEGIN 

            (logger.info [ユーザ認証情報を取得します] = " + loginUser);
             リターン 新しい新SimpleAuthenticationInfo(loginUser、authenticationToken.getCredentials()、   この.getName()); 
        } キャッチ(例外E){ 
            logger.error(" 異常取得したユーザ認証情報" 、E);
             戻り NULL ; 
        } 
    } 


    @Overrideは
    保護AuthorizationInfoをdoGetAuthorizationInfo(principalCollection principalCollection){ 
        SSOLoginUser loginUser = (SSOLoginUser)principalCollection.getPrimaryPrincipal(); 
        文字列アカウント = loginUser.getLoginName(); // ログイン

        一覧<ストリング> perms_string = saasPermissionExMapper.queryPermissionCodesOfUser(loginUser.getId())。
        一覧 <文字列> roles_string = saasRoleExMapper.queryRoleCodesOfUser(loginUser.getId()); 

        SimpleAuthorizationInfo authorizationInfo = 新しいSimpleAuthorizationInfo(); 
        セット <文字列>の役割= 新しい HashSetの<文字列> (roles_string)。
        authorizationInfo.setRoles(ロール); 
        logger.info(" [获取用户授权信息(角色)] " +アカウント+ " = " + 役割)。

        セット <文字列>パーマ= 新しいですHashSetの<ストリング> (perms_string)。
        authorizationInfo.setStringPermissions(パーマ)。
        logger.info(" [获取用户授权信息(权限)] " +アカウント+ " = " + パーマ)。
        返すauthorizationInfoを。
    } 

    @Override 
    パブリックオブジェクトgetAuthorizationCacheKey(PrincipalCollectionプリンシパル){ 
        SSOLoginUser loginUser = (SSOLoginUser)principals.getPrimaryPrincipal(); 
        文字列のアカウント = loginUser.getLoginName(); // 登录名
        の戻り " -AuthInfo- " + アカウント。 
    }
    
 
    @Override 
    公共 ボイドclearCachedAuthorizationInfo(PrincipalCollectionプリンシパル){ 
        super.clearCachedAuthorizationInfo(プリンシパル)。
    } 
    @Override 
    公共 ボイドclearCachedAuthenticationInfo(PrincipalCollectionプリンシパル){ 
        super.clearCachedAuthenticationInfo(プリンシパル)。
    } 
    @Override 
    公共 ボイドclearCache(PrincipalCollectionプリンシパル){ 
        super.clearCache(プリンシパル)。
    } 
}

おそらくアイデアはこれです。

おすすめ

転載: www.cnblogs.com/thinkingandworkinghard/p/12375502.html