Shiro multi-user authorization authentication?

topic description

A JavaWeb project, the front and back ends are divided into member and admin to log in, with permission settings respectively.
has now completed five permission tables (a total of 10 tables, five for member and five for admin).
when configuring different users to log in, instead of using a path to log in, member logs through / member/login, admin through / admin/login.
I am not very familiar with shiro for a day or two, and now I am still looking at zhangkaitao shiro-example
feels that the multi-Realm, that is, ModularRealmAuthenticator class is not what I think. It can only look for multiple Realm according to the account.
blogs that read some csdn also have their own ways to write. They just add fields loginType in the login page, encapsulate AuthenticationToken, and
call realm through loginType. But my login belongs to two pages, and I need to return different path interceptions according to different user types.

clipboard.png

in addition to judging Realm, we also need to return different path interceptors. I don"t have an idea yet.
it would be nice to have a big reminder. Otherwise, you will have to wait for yourself to solve the problem and upload the answer.

sources of topics and their own ideas

override DefaultFilterChainManager or PathMatchingFilter, adding different intercepts according to different users.
instantiate ShiroFilterFactoryBean according to different settings.

related codes

/ / Please paste the code text below (do not replace the code with pictures)

now MyRealm is configured with two kinds of user access information:

package com.tansuo365.test1.realm;

import com.tansuo365.test1.bean.Member;
import com.tansuo365.test1.bean.User;
import com.tansuo365.test1.entity.MyLoginInstance;
import com.tansuo365.test1.service.*;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.pam.AuthenticationStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
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.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Set;

@Component
public class MyRealm extends AuthorizingRealm {
    
    @Autowired
    private MemberService memberService;//member
    @Autowired
    private UserService userService;//user

    @Autowired
    private MroleService mroleService;//member
    @Autowired
    private RoleService roleService; //user

    @Autowired
    private MemberPermissionService memberPermissionService;//member
    @Autowired
    private PermissionService permissionService;//user


    /**/
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo info = null;
        //
        String loginType = (String)SecurityUtils.getSubject().getSession().getAttribute("loginType");
        Set<String> permissions = null;
        Set<String> roles = null;

        // 
        String username = (String)principals.getPrimaryPrincipal();

        if(LoginEnum.ADMIN.toString().equals(loginType)){

            permissions = permissionService.listPermissions(username);
            roles = roleService.listRoleNames(username);
        }
        if(LoginEnum.MEMBER.toString().equals(loginType)){
//            Member member = memberService.getByName(username);
            // service
            permissions = memberPermissionService.listMemberPermissions(username);
            roles = mroleService.listMroleNames(username);
        }
        // 
        info = new SimpleAuthorizationInfo();
        // service
        info.setStringPermissions(permissions);
        info.setRoles(roles);
        return info;
    }

    /**/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        User user = null;//
        Member member = null;//
        MyLoginInstance instance = null;//


        //1.AuthenticationTokenCustomizedToken
        CustomizedToken customizedToken = (CustomizedToken)token;
        //2.CustomizedTokenmemberName
        String nameInInput = customizedToken.getUsername();
        //3.,UnknownAccountException
        String loginType = customizedToken.getLoginType();
        if(LoginEnum.ADMIN.toString().equals(loginType)){
            user = userService.getByName(nameInInput);
            if(null == user){
                throw new UnknownAccountException("!");
            }
        }
        if(LoginEnum.MEMBER.toString().equals(loginType)){
            member = memberService.getByName(nameInInput);
            if(null == member){
                throw new UnknownAccountException("!");
            }
        }

        //4.,AuthenticationInfo
        //SimpleAuthenticationInfo
        Object principal = instance.getInstanceName();
        Object credentials = instance.getInstancePassword();
        String salt = instance.getInstanceSalt();
        String realmName = getName();
        ByteSource credentialsSalt = ByteSource.Util.bytes(salt);

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal,credentials,credentialsSalt,realmName);
        return info;
    }
}

but the problem is that the path has not been adjusted yet:
there is only one admin:

package com.tansuo365.test1.filter;

import com.tansuo365.test1.service.PermissionService;
import com.tansuo365.test1.util.SpringContextUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.PathMatchingFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.util.Set;

/*URL*/
public class URLPathMatchingFilter extends PathMatchingFilter {
    @Autowired
    private PermissionService permissionService;

    /**/
    @Override
    protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue)
            throws Exception {
        if(null==permissionService)
            permissionService = SpringContextUtils.getContext().getBean(PermissionService.class);

        String requestURI = getPathWithinApplication(request);
        System.out.println("requestURI:" + requestURI);

        Subject subject = SecurityUtils.getSubject();
        //  --
        if (!subject.isAuthenticated()) {
            WebUtils.issueRedirect(request, response, "/admin/login");
            return false;
        }

        // ()
        System.out.println("permissionService:"+permissionService);
        boolean needInterceptor = permissionService.needInterceptor(requestURI);
        if (!needInterceptor) {
            return true;
        } else {
            boolean hasPermission = false;
            String userName = subject.getPrincipal().toString();
            Set<String> permissionUrls = permissionService.listPermissionURLs(userName);
            for (String url : permissionUrls) {
                // 
                if (url.equals(requestURI)) {
                    hasPermission = true;
                    break;
                }
            }

            if (hasPermission)
                return true;
            else {
                UnauthorizedException ex = new UnauthorizedException(" " + requestURI + " ");

                subject.getSession().setAttribute("ex", ex);

                WebUtils.issueRedirect(request, response, "/admin/unauthorized");
                return false;
            }

        }

    }
}

ShiroConfiguration also has only admin:

package com.tansuo365.test1.shiro;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.tansuo365.test1.filter.URLPathMatchingFilter;
import com.tansuo365.test1.realm.AdminRealm;

import com.tansuo365.test1.realm.MyRealm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

//import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;

/**/
@Configuration
public class ShiroConfiguration {
//    @Autowired
//    private MemberShiroConfiguration memberShiroConfiguration;

    //thymeleafshiro
    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }

    @Bean
    public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }


    /**
     * ShiroFilterFactoryBean 
     * :ShiroFilterFactoryBean
     * ShiroFilterFactoryBean:SecurityManager
     * 

* Filter Chain * 1URLFilter * 2 * 3permsroles */ @Bean public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) { System.out.println("ShiroConfiguration.shirFilter()"); ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); //TODO 2019-1-29 17:40 //urlapplication.properties //securityManager //customisedFilterhashmapurlURLPath...Filter //customisedFilterHashMap(adminadmin,membermember) //filterChainDefinitionMap //1.securityManagerrealm //2.shiroFilterFactoryBeanset...Url //3.shiroFilterFactoryBean.setFilters(customisedFilter);customisedFilter //**customisedFilterput"url",valueURL() //4.shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); //**filterChainDefinitionMap // SecurityManager shiroFilterFactoryBean.setSecurityManager(securityManager); // Web"/login.jsp" shiroFilterFactoryBean.setLoginUrl("/admin/login"); ///login // shiroFilterFactoryBean.setSuccessUrl("/admin/"); ///index //; shiroFilterFactoryBean.setUnauthorizedUrl("/admin/unauthorized"); ///unauthorized //. Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>(); // Map<String, Filter> customisedFilter = new HashMap<>(); customisedFilter.put("url", getURLPathMatchingFilter()); // anon filterChainDefinitionMap.put("/admin/login", "anon"); // filterChainDefinitionMap.put("/admin/index", "anon"); filterChainDefinitionMap.put("/static/**", "anon"); filterChainDefinitionMap.put("/admin/config/**", "anon"); filterChainDefinitionMap.put("/admin/doLogout", "logout"); ;// // member filterChainDefinitionMap.put("/member/doLogout","logout");// filterChainDefinitionMap.put("/admin/**", "url"); ///shiro_admin/** // authc user filterChainDefinitionMap.put("/admin/**", "user"); shiroFilterFactoryBean.setFilters(customisedFilter); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } // public public URLPathMatchingFilter getURLPathMatchingFilter() { return new URLPathMatchingFilter(); } /**/ @Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //realm. securityManager.setRealm(getMyRealm()); // securityManager.setRememberMeManager(rememberMeManager()); // SecurityUtils.setSecurityManager(securityManager); return securityManager; } // @Bean // public AdminRealm getAdminRealm(){ // AdminRealm adminRealm = new AdminRealm(); // adminRealm.setCredentialsMatcher(hashedCredentialsMatcher()); // return adminRealm; // } @Bean public MyRealm getMyRealm(){ MyRealm myRealm = new MyRealm(); myRealm.setCredentialsMatcher(hashedCredentialsMatcher()); return myRealm; } // @Bean // public MemberRealm getMemberRealm(){ // MemberRealm memberRealm = new MemberRealm(); // memberRealm.setCredentialsMatcher(hashedCredentialsMatcher()); // return memberRealm; // } // @Bean // public DatabaseRealm getDatabaseRealm() { // DatabaseRealm myShiroRealm = new DatabaseRealm(); // myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher()); // return myShiroRealm; // } // @Bean // public MemberDatabaseRealm getMemberDatabaseRealm() { // MemberDatabaseRealm memberShiroRealm = new MemberDatabaseRealm(); // memberShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher()); // return memberShiroRealm; // } /** * * ShiroSimpleAuthenticationInfo * doGetAuthenticationInfo; * * * @return */ @Bean public HashedCredentialsMatcher hashedCredentialsMatcher() { HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); hashedCredentialsMatcher.setHashAlgorithmName("md5");//:MD5; hashedCredentialsMatcher.setHashIterations(2);// md5(md5("")); return hashedCredentialsMatcher; } /** * cookie,Cookie,:JSESSIONID * * @return */ @Bean public SimpleCookie rememberMeCookie() { SimpleCookie simpleCookie = new SimpleCookie("rememberMe"); simpleCookie.setHttpOnly(true); simpleCookie.setPath("/admin/"); simpleCookie.setMaxAge(60 * 60 * 24 * 30);//cookie return simpleCookie; } /** * cookie,,rememberMe * * @return */ @Bean public CookieRememberMeManager rememberMeManager() { CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); cookieRememberMeManager.setCookie(rememberMeCookie()); cookieRememberMeManager.setCipherKey(Base64.decode("4AvVhmFLUs0KTA3Kprsdag==")); return cookieRememberMeManager; } /** * FormAuthenticationFilter * * @return */ @Bean public FormAuthenticationFilter formAuthenticationFilter() { FormAuthenticationFilter formAuthenticationFilter = new FormAuthenticationFilter(); formAuthenticationFilter.setRememberMeParam("rememberMe"); return formAuthenticationFilter; } /** * shiro aop. * ;; * * @param securityManager * @return */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } }

what result do you expect? What is the error message actually seen?

member login is based on member"s realm, admin is based on admin"s
and path blocking (loginUrl,successUrl...) It will also be set up according to different settings.

May.29,2022
Menu