在上一个记录http://blog.csdn.net/oyh1203/article/details/72235915中初步搭建了一个springboot的项目,现在想将shiro也整合到项目中去,不多说,动手搞,项目结构如图
其它shiro相关的实现类不贴了
shiro配置信息都放到properties文件中文件内容如下
#SHIRO登录成功的URL地址
shiro.login.successUrl=/sayHello
#SHIRO登录地址
shiro.login.loginUrl=/
#SHIRO无权限跳转地址
shiro.login.unauthorizedUrl=/unauthorizedUrl
#SHIRO密码出错次数
shiro.login.errorTimes=5
#SHIRO有关cache的配置文件路径
shiro.login.cacheFilePath=classpath:xml/spring-shiro-ehcache.xml
#SHIRO加密方式
shiro.login.hashAlgorithmName=MD5
#SHIRO加密次数
shiro.login.hashIterations=3
shiro配置信息由xml改为代码配置,此处的私有属性通过ConfigurationProperties设置到对应的字段中,使用PropertySource指定配置文件路径,感谢博客园Gin.p
提供的Spring Boot整合shiro出现UnavailableSecurityManagerException异常解决方案
package com.test.ouyang.configure;
import java.util.LinkedHashMap;
import java.util.logging.Logger;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.filter.DelegatingFilterProxy;
import com.test.ouyang.realm.ResourceCheckFilter;
import com.test.ouyang.realm.RetryLimitHashedCredentialsMatcher;
import com.test.ouyang.realm.UserRealm;
@Configuration
@ConfigurationProperties(ignoreUnknownFields = false,prefix = "shiro.login")
@PropertySource("classpath:config/shiro.properties")
public class ShiroConfiguration {
private Logger log_ = Logger.getLogger(ShiroConfiguration.class.getName());
private String successUrl ;
private String loginUrl ;
private String unauthorizedUrl ;
private String cacheFilePath ;
private int errorTimes ;
private String hashAlgorithmName ;
private int hashIterations ;
public String getSuccessUrl() {
return successUrl;
}
public void setSuccessUrl(String successUrl) {
this.successUrl = successUrl;
}
public String getLoginUrl() {
return loginUrl;
}
public void setLoginUrl(String loginUrl) {
this.loginUrl = loginUrl;
}
public String getUnauthorizedUrl() {
return unauthorizedUrl;
}
public void setUnauthorizedUrl(String unauthorizedUrl) {
this.unauthorizedUrl = unauthorizedUrl;
}
public String getCacheFilePath() {
return cacheFilePath;
}
public void setCacheFilePath(String cacheFilePath) {
this.cacheFilePath = cacheFilePath;
}
public int getErrorTimes() {
return errorTimes;
}
public void setErrorTimes(int errorTimes) {
this.errorTimes = errorTimes;
}
public String getHashAlgorithmName() {
return hashAlgorithmName;
}
public void setHashAlgorithmName(String hashAlgorithmName) {
this.hashAlgorithmName = hashAlgorithmName;
}
public int getHashIterations() {
return hashIterations;
}
public void setHashIterations(int hashIterations) {
this.hashIterations = hashIterations;
}
/**
* delegatingFilterProxy方法参考http://www.cnblogs.com/ginponson/p/6217057.html
* 修复Spring Boot整合shiro出现UnavailableSecurityManagerException 问题
* 此处设置相当于在web.xml中增加filter
* */
@Bean
public FilterRegistrationBean delegatingFilterProxy(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
DelegatingFilterProxy proxy = new DelegatingFilterProxy();
proxy.setTargetFilterLifecycle(true);
proxy.setTargetBeanName("shiroFilter");
filterRegistrationBean.setFilter(proxy);
return filterRegistrationBean;
}
@Bean(name="resourceCheckFilter")
public ResourceCheckFilter resourceCheckFilter(){
ResourceCheckFilter resourceCheckFilter = new ResourceCheckFilter(unauthorizedUrl);
return resourceCheckFilter;
}
// SHIRO核心拦截器配置
@Bean(name="shiroFilter")
public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) {
log_.info("successUrl:"+successUrl+"\t loginUrl:"+loginUrl+"\t unauthorizedUrl:"+unauthorizedUrl);
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(securityManager);
bean.setSuccessUrl(successUrl);
bean.setLoginUrl(loginUrl);
bean.setUnauthorizedUrl(unauthorizedUrl);
//配置访问权限
LinkedHashMap<String, String> filterChainDefinitionMap=new LinkedHashMap<String, String>();
filterChainDefinitionMap.put("/adminView", "authc,resourceCheckFilter");
filterChainDefinitionMap.put("/testView", "authc,resourceCheckFilter");
filterChainDefinitionMap.put("/guestView", "authc,resourceCheckFilter");
filterChainDefinitionMap.put("/", "anon");
filterChainDefinitionMap.put("/static/**", "anon");
bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return bean ;
}
//配置SHIRO核心安全事务管理器
@Bean(name="securityManager")
public DefaultWebSecurityManager securityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
defaultWebSecurityManager.setRealm(userRealm);
return defaultWebSecurityManager;
}
//配置自定义的权限登录器
@Bean(name="userRealm")
public UserRealm userRealm(@Qualifier("credentialsMatcher") RetryLimitHashedCredentialsMatcher credentialsMatcher){
UserRealm userRealm = new UserRealm();
userRealm.setCredentialsMatcher(credentialsMatcher);
return userRealm;
}
//配置密码对比
@Bean(name="credentialsMatcher")
public RetryLimitHashedCredentialsMatcher credentialsMatcher(@Qualifier("cacheManager") EhCacheManager cacheManager){
RetryLimitHashedCredentialsMatcher credentialsMatcher = new RetryLimitHashedCredentialsMatcher(cacheManager,errorTimes,hashAlgorithmName,hashIterations);
return credentialsMatcher;
}
//配置缓存管理
@Bean(name="cacheManager")
public EhCacheManager cacheManager(){
EhCacheManager cacheManager = new EhCacheManager();
cacheManager.setCacheManagerConfigFile(cacheFilePath);
return cacheManager;
}
}
登录方法中使用shiro来校验用户信息
@RequestMapping("/login")
public String login(@RequestParam(value="account")String account,@RequestParam(value="password") String password){
Subject subject = SecurityUtils.getSubject();
log_.info("account:"+account+"\t password:"+password);
if(!account.equals(subject.getPrincipal())||!subject.isAuthenticated()){
UsernamePasswordToken token = new UsernamePasswordToken(account, password);
try {
subject.login(token);
} catch (UnknownAccountException uae) {
//用户名不存在
log_.info("用户名或密码错误");
}catch (IncorrectCredentialsException ice) {
//密码错误
log_.info("用户名或密码错误");
}catch (LockedAccountException lae) {
//账户被锁定
log_.info("账户被锁定");
}catch(ExcessiveAttemptsException eae){
//登录失败次数超过系统最大次数,请稍后重试
log_.info("登录失败次数超过系统最大次数,请稍后重试!");
}catch (Exception e) {
//出现其他异常
}
}
return "index";
}
源码内容见附件springboot.zip下载链接为:http://download.csdn.net/detail/oyh1203/9846996