如何使用 Spring Boot 配置 Shiro

Posted

技术标签:

【中文标题】如何使用 Spring Boot 配置 Shiro【英文标题】:How to configure Shiro with Spring Boot 【发布时间】:2014-10-04 04:39:53 【问题描述】:

我有一个 Spring MVC Web 应用程序,它使用 Spring 配置而不是 shiro.ini 来使用 Shiro 身份验证。

我想转换到 Spring Boot 应用程序。

我主要是成功的。应用程序在 Spring Boot 中启动,我的 Shiro 环境得到设置。但是我只是无法弄清楚如何正确设置 Shiro 过滤器。我需要这样做以确保请求最终由正确的线程处理。

在原始应用程序中,我在 web.xml 中配置了 Shiro 过滤器,如下所示:

<filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>targetFilterLifecycle</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

我已经尝试使用这样的 Java Config 复制它:

  @Autowired
  private WebSecurityManager webSecurityManager;

  @Bean
  public ShiroFilterFactoryBean shiroFilterFactoryBean() 
    ShiroFilterFactoryBean shiroFilterFactoryBean = new org.apache.shiro.spring.web.ShiroFilterFactoryBean();
    shiroFilterFactoryBean.setSecurityManager(webSecurityManager);
    return shiroFilterFactoryBean;
  

  @Bean
  public org.apache.shiro.spring.LifecycleBeanPostProcessor lifecycleBeanPostProcessor()
  
    return new org.apache.shiro.spring.LifecycleBeanPostProcessor();
  

  @Bean
  public Filter shiroFilter()
  
    DelegatingFilterProxy filter = new DelegatingFilterProxy();
    filter.setTargetBeanName("shiroFilterFactoryBean");
    filter.setTargetFilterLifecycle(true);
    return filter;
  

但是,我无法将所有内容组合在一起,也没有足够的知识来解决问题。我只是看不到将过滤器连接到环境。我猜这与设置的顺序有关。

有人成功地同时使用了 Spring Boot 和 Shiro 吗?

【问题讨论】:

在 Spring Boot 应用程序中通常不需要 DelegatingFilterProxy。如果ShiroFilterFactoryBean 创建了Filter,那么它应该默认应用于所有请求。 @Daniel Vaughan 完成后能否分享代码库 【参考方案1】:

嗯,好像少了点什么,java config是这样的:

import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import org.apache.shiro.realm.text.PropertiesRealm;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.web.filter.authc.AnonymousFilter;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.apache.shiro.web.filter.authc.UserFilter;
import org.apache.shiro.web.filter.authz.RolesAuthorizationFilter;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.mgt.WebSecurityManager;

@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean shiroFilter() 
    ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
    shiroFilter.setLoginUrl("/login");
    shiroFilter.setSuccessUrl("/index");
    shiroFilter.setUnauthorizedUrl("/forbidden");
    Map<String, String> filterChainDefinitionMapping = new HashMap<String, String>();
    filterChainDefinitionMapping.put("/", "anon");
    filterChainDefinitionMapping.put("/home", "authc,roles[guest]");
    filterChainDefinitionMapping.put("/admin", "authc,roles[admin]");
    shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMapping);
    shiroFilter.setSecurityManager(securityManager());
    Map<String, Filter> filters = new HashMap<String, Filter>();
    filters.put("anon", new AnonymousFilter());
    filters.put("authc", new FormAuthenticationFilter());
    filters.put("logout", new LogoutFilter());
    filters.put("roles", new RolesAuthorizationFilter());
    filters.put("user", new UserFilter());
    shiroFilter.setFilters(filters);
    System.out.println(shiroFilter.getFilters().size());
    return shiroFilter;


@Bean(name = "securityManager")
public SecurityManager securityManager() 
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    securityManager.setRealm(realm());
    return securityManager;


@Bean(name = "realm")
@DependsOn("lifecycleBeanPostProcessor")
public PropertiesRealm realm() 
    PropertiesRealm propertiesRealm = new PropertiesRealm();
    propertiesRealm.init();
    return propertiesRealm;


@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() 
    return new LifecycleBeanPostProcessor();

https://github.com/lenicliu/eg-spring/tree/master/eg-spring-boot/eg-spring-boot-shiro

【讨论】:

答案非常适合但仍然得到:org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager 可访问调用代码,绑定到 org.apache.shiro.util.ThreadContext 或作为 vm 静态单身人士。这是一个无效的应用程序配置。 这里有一个例子,也许它会对你有所帮助。 github.com/lenicliu/eg-spring/tree/master/eg-spring-boot/…【参考方案2】:

lenicliu 提供了很好的信息,因为我没有足够的声誉,所以我无法评论他的回答。我想添加我必须为他的代码实际编译所做的所有导入(可能对 Shiro 上的新手有用,比如我)。

import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import org.apache.shiro.realm.text.PropertiesRealm;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.web.filter.authc.AnonymousFilter;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.apache.shiro.web.filter.authc.UserFilter;
import org.apache.shiro.web.filter.authz.RolesAuthorizationFilter;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.mgt.WebSecurityManager;

【讨论】:

这应该是对另一个答案的编辑,而不是单独的答案。 好的,谢谢。正如我所说,我没有足够的代表来编辑其他答案,但现在可以。

以上是关于如何使用 Spring Boot 配置 Shiro的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot + Mongodb + Shiro配置

[Shiro]Shiro整合Spring Boot 自动化配置

十 Spring Boot Shiro 权限管理

解决Spring Boot集成Shiro,配置类使用Autowired无法注入Bean问题

Spring Boot Shiro 权限管理

Spring Boot Shiro 权限管理