在上一个记录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";
- }