SpringSecurity - 授权、权限

本文详细介绍了Spring Security中用于权限控制的方法,包括anyRequest()、authenticated()、antMatchers()、regexMatchers()、mvcMatchers()、hasAuthority()、hasRole()、hasIpAddress()以及自定义403页面。通过示例代码展示了如何配置这些方法来实现不同场景下的权限控制,如放行静态资源、基于角色和权限的访问限制、IP地址限制以及自定义错误页面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 授权(权限)

常用方法 - 以下方法都需要组合起来才能使用。

(1)anyRequest()

任何请求,注意需要把它放到最后边

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 自定义登录页面
        http.formLogin()
                .loginPage("/login.html");

        // 在这里写授权逻辑
        // 除了login api接口,其他api接口都需要拦截,做授权
        http.authorizeRequests()
                .antMatchers("/login").permitAll()
                // 任何请求都需要授权,注意顺序 从上至下
                .anyRequest().authenticated();

        // 关闭csrf防护
        http.csrf().disable();
    }

    @Bean
    public PasswordEncoder bCryptPasswordEncoder () {
        return new BCryptPasswordEncoder();
    }
}

(2)authenticated()

所有请求必须认证才能访问,但是,一写静态资源:如:css、js,不需要授权,此时就需要antMatchers() 了。
 

(3)antMatchers()

需要放行的api、静态资源、目录等。

参数一:可以放行指定的请求方法(只写一个参数的话,代表任何的请求方法都可以)。
参数二:api接口,或一个.html页面。

参数一是必定向参数,每个参数是一个ant表达式,用于匹配URL规则。

规则如下:

匹配一个字符

匹配0个或多个字符

** 匹配0个或多个目录

 在实际项目中,经常需要放行所有的静态资源,如下:

antMatchers("/js/**", "/css/**").permitAll();

 还有一种放行方式,如下:只要是.js文件都放行

antMatchers("/**/*.js").permitAll();

只要是图片jpg或png就放行

antMatchers("/**/*.jpg", "/**/*.png").permitAll()

 如:

(1) 只放行static和public目录下的所有文件。

http.authorizeRequests()
        // /login接口不需要授权
        .antMatchers("/static/**").permitAll()
        .antMatchers("/public/**").permitAll()
        // 任何请求都需要授权
        .anyRequest().authenticated();

(2)放行login.html 、error.html、static目录下的css目录及js目录:

// 请求授权
http.authorizeRequests()
        // 匹配一个可以放行的路径
        .mvcMatchers("/login.html", "/error.html", "/css/**", "/js/**")
        .permitAll()
        .anyRequest().authenticated(); // 任何请求都需要授权

(4).regexMatchers() 

正则匹配。

参数一:可以放行指定的请求方法(只写一个参数的话,代表任何的请求方法都可以)。。
参数二:api接口,或一个正则表达式。

例:只放行get请求方法的 /demo 接口

.regexMatchers(HttpMethod.GET, "/demo").permitAll()

(5)mvcMatchers() 

MVC匹配。

只要是 /test/demo的api就放行,下边的servletPath() 与下边配置文件中的servlet.path 对应,如果加上此配置,访问所有的api都需要加上前缀 /test 

.mvcMatchers("/demo").servletPath("/test").permitAll()

这个 mvcMatchers("/demo").servletPath("/test") 相当于 antMatchers("/demo/test")

servletPath这个方法只在mvcMatchers()方法中才有。

(6)基于权限来控制访问 - hasAuthority("权限")

1、

.mvcMatchers("/main.html").hasAuthority("superAdmin") 注意权限大小写敏感!!!

用户登录之后,假设某些页面需要拥有某个权限才能访问:

登陆成功,进入登陆成功页面,如果想进入主页面,需要superAdmin这个权限才能访问,

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 表单的登录
        // ··· ···
        // 请求授权
        http.authorizeRequests()
                // 匹配一组可以放行的路径
                .mvcMatchers("/login.html", "/error.html", "/css/**", "/js/**", "/**/*.jpg")
                .permitAll()
                 // 这个main.html需要superAdmin权限才能访问
                .mvcMatchers("/main.html")
                .hasAuthority("superAdmin")
                .anyRequest().authenticated(); // 任何请求都需要授权
            }
}

点击,403禁止访问,也就是没有这个权限,这个权限我们在下边可以配置:

 当给这个用户加上superAdmin后,在访问时,就可以进入main.html页面了

 

2、多个权限 - hasAnyAuthority( "权限1",  "权限2",  ··· ··· )

如果访问某个页面对应多个权限,也就是有其中一个权限就能访问该页面,用如下方法

 (7)基于角色来控制访问  - hasRole("角色")

如何添加角色呢?
也很简单,也是在添加权限这里加,与权限区别在于:角色前边必须添加 ROLE_

 使用:

.mvcMatchers("/main.html").hasRole("lxc") // 添加lxc角色,也可以使用 hasAnyRole("角色", ··· ···)添加多个角色

 

 (8)基于ip地址去控制访问 - hasIpAddress("ip地址")

在实际开发中,有事会有这样的需求:只有这一台服务器才能访问某个api地址,那么我们可以用基于ip地址去控制访问(只有这个ip地址才能登陆,如果不是这个ip地址就不允许登陆)。

 此时用localhost访问main.html直接禁止访问了

 改用127.0.0.1试下,成功:

 (9)自定义403页面

 之前如果访问没有权限的页面会出现403页面,自定义的话,如下:

1、首先 实现 AccessDeniedHandler接口,重写方法 

package com.lxc.sequrity.config;

import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@Component
public class PageForbidenHandler implements AccessDeniedHandler {
    @Override
    public void handle(
            HttpServletRequest httpServletRequest,
            HttpServletResponse httpServletResponse,
            AccessDeniedException e) throws IOException, ServletException {
        httpServletResponse.setHeader("Content-Type", "application/json;charset=utf-8");
        httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
        PrintWriter writer = httpServletResponse.getWriter();
        writer.write("{\"msg\": 权限不足,不能访问}");
        writer.flush();
        writer.close();
    }
}

2、在配置类中,注入,配置:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    PageForbidenHandler pageForbidenHandler;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // ··· ···

        // 403异常处理    
        http.exceptionHandling()
                .accessDeniedHandler(pageForbidenHandler);
    }
}

(10) access()方法

上边所有放行的方法,内部都是基于access()方法调用的,比如 :

.mvcMatchers().permitAll()、.mvcMatchers().hasAuthority()、··· ···

 所有的放行方法,都可以用access()方法来实现,效果完成一样的:

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值