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.
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.