SpringBoot整合SpringSecurity(六)权限注解

序言

这一篇说一下比较好用的Spring Security注解。

代码请参考 https://github.com/AutismSuperman/springsecurity-example

使用

Spring Security默认是禁用注解的,要想开启注解,要在继承WebSecurityConfigurerAdapter的类加@EnableMethodSecurity注解,并在该类中将AuthenticationManager定义为Bean。

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled=true,jsr250Enabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

我们看到@EnableGlobalMethodSecurity 分别有prePostEnabledsecuredEnabledjsr250Enabled 三个字段,其中每个字段代码一种注解支持,默认为false,true为开启。那么我们就一一来说一下这三总注解支持。

JSR-250注解

主要注解

  • @DenyAll
  • @RolesAllowed
  • @PermitAll

这里面@DenyAll@PermitAll 相信就不用多说了 代表拒绝和通过。

@RolesAllowed 使用示例

@RolesAllowed({"USER", "ADMIN"})

代表标注的方法只要具有USER, ADMIN任意一种权限就可以访问。这里可以省略前缀ROLE_,实际的权限可能是ROLE_ADMIN

securedEnabled注解

主要注解

  • @Secured

@Secured在方法上指定安全性要求

可以使用@Secured在方法上指定安全性要求 角色/权限等 只有对应 角色/权限 的用户才可以调用这些方法。 如果有人试图调用一个方法,但是不拥有所需的 角色/权限,那会将会拒绝访问将引发异常。

@Secured使用示例

@Secured("ROLE_ADMIN")
@Secured({ "ROLE_DBA", "ROLE_ADMIN" })

还有一点就是@Secured,不支持Spring EL表达式

prePostEnabled注解

这个开启后支持Spring EL表达式 算是蛮厉害的。如果没有访问方法的权限,会抛出AccessDeniedException

主要注解

  • @PreAuthorize --适合进入方法之前验证授权

  • @PostAuthorize --检查授权方法之后才被执行

  • @PostFilter --在方法执行之后执行,而且这里可以调用方法的返回值,然后对返回值进行过滤或处理或修改并返回

  • @PreFilter --在方法执行之前执行,而且这里可以调用方法的参数,然后对参数值进行过滤或处理或修改

@PreAuthorize 使用例子

在方法执行之前执行,而且这里可以调用方法的参数,也可以得到参数值,这里利用JAVA8的参数名反射特性,如果没有JAVA8,那么也可以利用Spring Secuirty的@P标注参数,或利用Spring Data的@Param标注参数。

//无java8
@PreAuthorize("#userId == authentication.principal.userId or hasAuthority(‘ADMIN’)")
void changePassword(@P("userId") long userId ){}
//有java8
@PreAuthorize("#userId == authentication.principal.userId or hasAuthority(‘ADMIN’)")
void changePassword(long userId ){}

这里表示在changePassword方法执行之前,判断方法参数userId的值是否等于principal中保存的当前用户的userId,或者当前用户是否具有ROLE_ADMIN权限,两种符合其一,就可以访问该 方法。

@PostAuthorize 使用例子

在方法执行之后执行,而且这里可以调用方法的返回值,如果EL为false,那么该方法也已经执行完了,可能会回滚。EL变量returnObject表示返回的对象。

@PostAuthorize("returnObject.userId == authentication.principal.userId or hasPermission(returnObject, 'ADMIN')")
User getUser();

@PostFilter

在执行方法之后执行,而且这里可以调用方法的返回值,然后对返回值进行过滤或处理。EL变量returnObject表示返回的对象。只有方法返回的集合或数组类型的才可以使用。(与分页技术不兼容)

@PreFilter

EL变量filterObject表示参数,如果有多个参数,可以使用@filterTarget注解参数,只有方法是集合或数组才行(与分页技术不兼容)。

自定义匹配器

另外说一点就是@PreAuthorize@PostAuthorize 中 除了支持原有的权限表达式之外,也是可以支持自定义的。

比如

定义一个自己的权限匹配器

interface TestPermissionEvaluator {
    boolean check(Authentication authentication);
}

@Service("testPermissionEvaluator")
public class TestPermissionEvaluatorImpl implements TestPermissionEvaluator {

    public boolean check(Authentication authentication) {
        System.out.println("进入了自定义的匹配器" + authentication);
        return false;
    }
}

返回true 就是有权限 false 则是无权限 。 然后在方法中这样玩即可

@PreAuthorize("@testPermissionEvaluator.check(authentication)")
public String test0() {
	return "说明你有自定义权限";
}

异常处理

然后呢异常处理类跟之前一样

@Component
@Slf4j
public class AccessDeniedAuthenticationHandler implements AccessDeniedHandler {
    private final ObjectMapper objectMapper;

    public AccessDeniedAuthenticationHandler(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException {
        log.info("没有权限");
        httpServletResponse.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        httpServletResponse.getWriter().write(objectMapper.writeValueAsString(e.getMessage()));
    }

}

然后在WebSecurityConfig 中的 configure 中配置即可

http.anyRequest()
    .authenticated()
    .and().exceptionHandling()
    .accessDeniedHandler(accessDeniedAuthenticationHandler);

下一篇我们就来说一下SpringSecurity 这个权限校验是一个怎样的流程。

本博文是基于springboot2.x 和security 5 如果有什么不对的请在下方留言。

  • 8
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Spring Security 是一个企业级安全框架,它提供了一系列的安全服务和基于标准的安全注解,帮助开发者在应用程序中实现身份认证和权限控制等功能。Spring Boot 是一个快速构建应用程序的框架,它提供了对 Spring 框架的自动配置,简化了项目的搭建和开发。将 Spring SecuritySpring Boot 结合使用,可以很方便地实现安全认证和授权功能。 下面是 Spring Boot 整合 Spring Security 的步骤: 1. 在 pom.xml 文件中添加 Spring Security 依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ``` 2. 创建一个 Security 配置类,用于配置 Spring Security 的相关参数,如安全拦截规则、用户认证方式等。可以继承 WebSecurityConfigurerAdapter 类,重写 configure 方法来实现配置。 ``` @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/user/**").hasRole("USER") .anyRequest().authenticated() .and() .formLogin() .and() .httpBasic(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("admin").password("{noop}admin123").roles("ADMIN") .and() .withUser("user").password("{noop}user123").roles("USER"); } } ``` 3. 在配置类中配置用户认证方式。可以使用内存认证、数据库认证或者 LDAP 认证等方式进行用户认证。 4. 配置安全拦截规则。可以通过 antMatchers 方法来设置 URL 的安全拦截规则,如 /admin/** 需要 ADMIN 角色才能访问,/user/** 需要 USER 角色才能访问。 5. 配置登录页面。可以通过 formLogin 方法来配置登录页面的 URL,如 /login。用户输入正确的用户名和密码后,会跳转到登录成功页面。 6. 配置 HTTP Basic 认证。可以通过 httpBasic 方法来开启 HTTP Basic 认证,这样客户端可以使用用户名和密码来访问受保护的资源。 通过上述步骤,就可以将 Spring Security 集成到 Spring Boot 应用程序中,实现安全认证和授权功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值