也需要从Realm得到用户相应的角色/权限进行验证用户是否能进行操作;可以把Realm看成DataSource , 即安全数据源。
package com.javon.boot.realm;
import com.javon.boot.service.UserService;
import com.javon.boot.vo.SysUser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.apache.shiro.util.ByteSource;
import javax.annotation.Resource;
import java.util.Set;
public class UserRealm extends AuthorizingRealm {
private Log log = LogFactory.getLog(UserRealm.class);
@Resource
private UserService userService;
@SuppressWarnings("unchecked")
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal();
Set allRoles = userService.findRoles(username);
Set allResources = userService.findPermissions(username);
if(allRoles.isEmpty()||allResources.isEmpty()){
log.error("未找到用户:"+username+"授权信息!");
}
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.setRoles(allRoles);
authorizationInfo.setStringPermissions(allResources);
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
SysUser user =userService.getByUserName(username);
if (user == null) {
log.info(username+"没找到帐号");
throw new UnknownAccountException();// 没找到帐号
}
if (user.getLocked()==1) {
log.info(username+"帐号锁定");
throw new LockedAccountException(); // 帐号锁定
}
// 密码验证
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUserName(), // 用户名
user.getPassword(), // 密码
ByteSource.Util.bytes(user.getCredentialsSalt()), // salt=username+salt
getName() // realm name
);
return authenticationInfo;
}
@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);
}
public void clearAllCachedAuthorizationInfo() {
getAuthorizationCache().clear();
}
public void clearAllCachedAuthenticationInfo() {
getAuthenticationCache().clear();
}
public void clearAllCache() {
clearAllCachedAuthenticationInfo();
clearAllCachedAuthorizationInfo();
}
}
2.最重要的shiroconfig文件编写
package com.javon.boot.config;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.session.mgt.eis.SessionIdGenerator;
import org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler;
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.filter.authc.LogoutFilter;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import com.javon.boot.realm.UserRealm;
import com.javon.boot.util.KickoutSessionControlFilter;
import com.javon.boot.util.RetryLimitHashedCredentialsMatcher;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.springframework.web.filter.DelegatingFilterProxy;
@Configuration
public class ShiroConfig {
@Bean
public UserRealm getRealm() {// 1、获取配置的Realm,之所以没使用注解配置,是因为此处需要考虑到加密处理
UserRealm realm = new UserRealm();
realm.setCredentialsMatcher(getRetryLimitHashedCredentialsMatcher());
realm.setCacheManager(getCacheManager());
realm.setCachingEnabled(false);
return realm;
}
@Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean
@DependsOn("lifecycleBeanPostProcessor")
public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
daap.setProxyTargetClass(true);
return daap;
}
@Bean
public EhCacheManager getCacheManager() {// 2、缓存配置
EhCacheManager cacheManager = new EhCacheManager();
cacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");
return cacheManager;
}
/*
* @Bean public HashedCredentialsMatcher getHashedCredentialsMatcher() {//
* 认证bean配置 HashedCredentialsMatcher credentialsMatcher = new
* HashedCredentialsMatcher();
* credentialsMatcher.setHashAlgorithmName("md5");
* credentialsMatcher.setHashIterations(2);
* credentialsMatcher.setStoredCredentialsHexEncoded(true); return
* credentialsMatcher; }
*/
@Bean // 登录次数限制
public RetryLimitHashedCredentialsMatcher getRetryLimitHashedCredentialsMatcher() {
RetryLimitHashedCredentialsMatcher retryLimitHashedCredentialsMatcher = new RetryLimitHashedCredentialsMatcher(
getCacheManager());
retryLimitHashedCredentialsMatcher.setHashAlgorithmName("md5");
retryLimitHashedCredentialsMatcher.setHashIterations(2);
retryLimitHashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
return retryLimitHashedCredentialsMatcher;
}
// 登录并发控制
public KickoutSessionControlFilter getKickoutSessionControlFilter(SessionManager sessionManager) {
KickoutSessionControlFilter kickoutSessionControlFilter = new KickoutSessionControlFilter();
kickoutSessionControlFilter.setCacheManager(getCacheManager());
kickoutSessionControlFilter.setSessionManager(sessionManager);
kickoutSessionControlFilter.setKickoutAfter(false);
kickoutSessionControlFilter.setMaxSession(1);
kickoutSessionControlFilter.setKickoutUrl("/login?kickout=1");
return kickoutSessionControlFilter;
}
// 配置此bean才能结合thymeleaf使用shiro页面标签语法
@Bean
public ShiroDialect getShiroDialect() {
return new ShiroDialect();
}
@Bean
public SessionIdGenerator getSessionIdGenerator() { // 3
return new JavaUuidSessionIdGenerator();
}
@Bean
public SessionDAO getSessionDAO(SessionIdGenerator sessionIdGenerator) { // 4
EnterpriseCacheSessionDAO sessionDAO = new EnterpriseCacheSessionDAO();
sessionDAO.setActiveSessionsCacheName("shiro-activeSessionCache");
sessionDAO.setSessionIdGenerator(sessionIdGenerator);
return sessionDAO;
}
@Bean
public QuartzSessionValidationScheduler getQuartzSessionValidationScheduler() {
QuartzSessionValidationScheduler sessionValidationScheduler = new QuartzSessionValidationScheduler();
sessionValidationScheduler.setSessionValidationInterval(100000);
return sessionValidationScheduler;
}
@Bean
public RememberMeManager getRememberManager() { // 5
CookieRememberMeManager rememberMeManager = new CookieRememberMeManager();
SimpleCookie cookie = new SimpleCookie("SysUser-RememberMe");
cookie.setHttpOnly(true);
cookie.setMaxAge(3600);
rememberMeManager.setCookie(cookie);
return rememberMeManager;
}
@Bean
public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(
DefaultWebSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
aasa.setSecurityManager(securityManager);
return aasa;
}
@Bean
public DefaultWebSessionManager getSessionManager(SessionDAO sessionDAO) { // 6
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setGlobalSessionTimeout(1000000);
sessionManager.setDeleteInvalidSessions(true);
sessionManager.setSessionValidationSchedulerEnabled(true);
sessionManager.setSessionDAO(sessionDAO);
SimpleCookie sessionIdCookie = new SimpleCookie("sid");
sessionIdCookie.setHttpOnly(true);
sessionIdCookie.setMaxAge(-1);
sessionManager.setSessionIdCookie(sessionIdCookie);
sessionManager.setSessionIdCookieEnabled(true);
return sessionManager;
}
@Bean
public DefaultWebSecurityManager getSecurityManager(Realm userRealm, EhCacheManager cacheManager,
SessionManager sessionManager, RememberMeManager rememberMeManager) {// 7
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm);
securityManager.setCacheManager(getCacheManager());
securityManager.setSessionManager(sessionManager);
securityManager.setRememberMeManager(rememberMeManager);
return securityManager;
}
public FormAuthenticationFilter getLoginFilter() { // 在ShiroFilterFactoryBean中使用
FormAuthenticationFilter filter = new FormAuthenticationFilter();
filter.setUsernameParam("username");
filter.setPasswordParam("password");
// filter.setRememberMeParam("rememberMe");
filter.setLoginUrl("/login"); // 登录提交页面
filter.setFailureKeyAttribute("shiroLoginFailure");// 登录失败提示信息
return filter;
}
public LogoutFilter getLogoutFilter() { // 在ShiroFilterFactoryBean中使用
LogoutFilter logoutFilter = new LogoutFilter();
logoutFilter.setRedirectUrl("/login"); // 首页路径,登录注销后回到的页面
return logoutFilter;
}
/*
用于解决监听当前登录用户信息报错
org.apache.shiro.util.ThreadContext or as a vm static singleton. This is an invalid application configuration.
*/
@Bean
public FilterRegistrationBean delegatingFilterProxy(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
DelegatingFilterProxy proxy = new DelegatingFilterProxy();
proxy.setTargetFilterLifecycle(true);
proxy.setTargetBeanName("shiroFilter");
filterRegistrationBean.setFilter(proxy);
return filterRegistrationBean;
}
/**
* 监听当前登录用户信息
* @return
*/
@Bean
public SysUserFilterConfig getSysUserFilterConfig(){
return new SysUserFilterConfig();
}
@Bean("shiroFilter")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 必须设置 SecurityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("/login"); // 设置登录页路径
shiroFilterFactoryBean.setSuccessUrl("/index"); // 设置跳转成功页
shiroFilterFactoryBean.setUnauthorizedUrl("/pages/unauthUrl"); // 授权错误页
Map filters = new HashMap();
filters.put("authc", this.getLoginFilter());
filters.put("logout", this.getLogoutFilter());
//添加获取当前登录用户filter
filters.put("sysUser", getSysUserFilterConfig());
// 登录并发拦截
filters.put("kickout", this.getKickoutSessionControlFilter(securityManager.getSessionManager()));
shiroFilterFactoryBean.setFilters(filters);
Map filterChainDefinitionMap = new HashMap();
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/login", "authc"); // 定义内置登录处理
filterChainDefinitionMap.put("/css/**", "anon");
filterChainDefinitionMap.put("/js/**", "anon");
filterChainDefinitionMap.put("/fonts/**", "anon");
filterChainDefinitionMap.put("/img/**", "anon");
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/kickout", "authc");
filterChainDefinitionMap.put("/**", "kickout,authc,sysUser");// 请求拦截路径
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
}
如需登录次数限制,用户踢出,和当前用户拦截源码,留言获取