在SpringBoot下结合shiro对静态资源实现认证访问权限控制

文章讲述了如何通过Shiro和SpringBoot对本地或云存储的静态资源进行权限控制。当文件存储在本地时,可以通过SpringBoot的资源配置结合Nginx的反向代理来访问;如果文件在云服务器,也可以直接配置SpringBoot映射资源路径。在所有情况下,都会通过Shiro进行认证判断,未授权访问会被重定向到登录页面。
摘要由CSDN通过智能技术生成

错误示例

1、我们通过localhost/profile/girl.jpg可以访问到美女图片,假设图片是存储在我们的服务器的/home/data目录下,我们可以通过nginx的反向静态资源代理可以直接将profile的请求文件转入到/home/data下去读取图片文件。
2、我们可以将图片直接存储至云服务器,或者一个外网访问地址例如:https://yunurl/profile/girl.jpg。这种情况我们无需配置nginx代理。
以上两种情况都是在用户未认证,拿到地址即可访问文件

解决方案

引入shiro,springboot对文件的请求路径增加映射时shiro进行认证权限判断。
我们同样分两种情况
1、文件存储在本地,即与应用在同一服务器,例如我们的文件是在/home/data目录下,我们可以通过此配置来映射
添加pom依赖

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <version>2.1.1.RELEASE</version>
</dependency>
 
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
@Configuration
public class SongConfig implements WebMvcConfigurer {
 
 
    @Value("${songPic.path}")
    private String songPicPath;
 
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //加载文件资源
        registry.addResourceHandler("/songPic/**").addResourceLocations("file:"+songPicPath);
    }
}

以上配置使得访问localhost/profile/girl.jpg时会映射至本地路径下去查找文件,并且shiro会先对此请求进行认证的权限访问,如果没有登录访问此链接则会跳转至登录页面。
2、对于存储在云端的文件,我们同样也需要对其进行认证校验,而做法如上一致,结合addResourceLocations的源码我们分析

 /**
     * Add one or more resource locations from which to serve static content.
     * Each location must point to a valid directory. Multiple locations may
     * be specified as a comma-separated list, and the locations will be checked
     * for a given resource in the order specified.
     * <p>For example, {{@code "/"}, {@code "classpath:/META-INF/public-web-resources/"}}
     * allows resources to be served both from the web application root and
     * from any JAR on the classpath that contains a
     * {@code /META-INF/public-web-resources/} directory, with resources in the
     * web application root taking precedence.
     * <p>For {@link org.springframework.core.io.UrlResource URL-based resources}
     * (e.g. files, HTTP URLs, etc) this method supports a special prefix to
     * indicate the charset associated with the URL so that relative paths
     * appended to it can be encoded correctly, e.g.
     * {@code [charset=Windows-31J]https://example.org/path}.
     * @return the same {@link ResourceHandlerRegistration} instance, for
     * chained method invocation
     */
    public ResourceHandlerRegistration addResourceLocations(String... resourceLocations) {
        this.locationValues.addAll(Arrays.asList(resourceLocations));
        return this;
    }

静态资源的映射支持类路径、本地文件、并且支持url方式的路径映射,因此假设文件存储在https://yunurl/profile/girl.jpg此云路径下。
我们可以同样来通过此方法来映射

 @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry)
    {
        registry.addResourceHandler("/profile/**").addResourceLocations("https://yunurl/profile");
    }

shiro对于请求路径的拦截是默认在authc过滤级别下,因此只要保证我们的项目请求能够并shiro拦截,并且路径能映射到静态资源文件,则可以满足静态文件的访问权限控制

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,需要在 pom.xml 文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-web-starter</artifactId> <version>1.6.0</version> </dependency> ``` 接着,在 application.yml 文件中配置 Shiro 和 LDAP 认证的相关信息: ```yaml shiro: ldap: url: ldap://localhost:10389 base: dc=example,dc=com userDnTemplate: uid={0},ou=people,dc=example,dc=com spring: ldap: urls: ldap://localhost:10389 base: dc=example,dc=com username: uid=admin,ou=system password: secret ``` 其中,url 配置的是 LDAP 服务器的地址和端口,base 是 LDAP 的根节点,userDnTemplate 则是用户节点的模板,用于根据用户名获取用户节点的 DN。 接下来,需要创建一个实现了 AuthenticationInfo 接口的类,用于获取用户的认证信息: ```java @Component public class LdapRealm extends AuthorizingRealm { @Autowired private LdapTemplate ldapTemplate; /** * 获取认证信息 * @param authenticationToken * @return * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; String username = token.getUsername(); String password = new String(token.getPassword()); // 根据用户名获取用户节点的 DN String userDn = ldapTemplate.lookup("uid=" + username, new String[]{"dn"}); // 验证用户密码 try { ldapTemplate.authenticate(userDn, "(objectClass=person)", password); } catch (AuthenticationException e) { throw new IncorrectCredentialsException("用户名或密码错误"); } return new SimpleAuthenticationInfo(username, password, getName()); } /** * 获取授权信息 * @param principalCollection * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { return null; } } ``` 这里使用了 Spring LDAP 的 LdapTemplate 进行 LDAP 认证,通过调用 authenticate 方法实现验证用户密码。 最后,在 WebSecurityConfig 配置类中开启 Shiro 和 LDAP 认证: ```java @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private LdapRealm ldapRealm; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/login").permitAll() .anyRequest().authenticated() .and() .formLogin().loginPage("/login").permitAll() .and() .logout().permitAll(); http.csrf().disable(); } @Override public void configure(WebSecurity web) throws Exception { web.ignoring() .antMatchers("/css/**", "/js/**", "/img/**"); } @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); return shiroFilterFactoryBean; } @Bean public DefaultWebSecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(ldapRealm); return securityManager; } } ``` 在这里,我们通过 configure 方法配置了登录页面、退出页面和权限控制,通过 configure(WebSecurity web) 方法配置了静态资源的忽略,最后通过 shiroFilterFactoryBean 和 securityManager 方法开启 Shiro 和 LDAP 认证
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值