Springboot整合SpringSecurity 07-方法访问权限控制

Springboot整合SpringSecurity 07-方法访问权限控制

前面我们已经学会了SpringSecurity的权限访问控制。
但是之前的配置都是直接对请求路径的权限控制,SpringSecurity还提供了访问级别的权限控制。
必须具有相应的权限才能访问该方法。

本系列的按顺序写的,如果对于某些代码不清楚,请看下前面的几篇文章。
Springboot整合SpringSecurity 01-使用入门
Springboot整合SpringSecurity 02-使用自定义登陆页面
Springboot整合SpringSecurity 03-访问权限控制
Springboot整合SpringSecurity 04-启用登出logout功能
Springboot整合SpringSecurity 05-使用JDBC实现认证和授权
Springboot整合SpringSecurity 06-登陆扩展之自定义登陆验证逻辑
Springboot整合SpringSecurity 07-方法访问权限控制

1. 添加权限控制的方法。

/**
 * @author flw
 */
public interface MethodSecureService {

    /**
     * 任何授权了的人都可以访问
     * @return
     */
    @Secured("IS_AUTHENTICATED_ANONYMOUSLY")
    String common();
    /**
     * ROLE_ADMIN权限访问
     * @return
     */
    @Secured("ROLE_ADMIN")
    String admin();
    /**
     * ROLE_USER or ROLE_DBA 权限访问。
     * @return
     */
    @Secured({"ROLE_USER", "ROLE_DBA"})
    String user();

    /**
     * 任何授权了的人都可以访问
     * @return
     */
    @PreAuthorize("isAuthenticated()")
    String common2();
    /**
     * ROLE_ADMIN权限访问
     * @return
     */
    @PreAuthorize("hasAuthority('ROLE_ADMIN')")
    String admin2();
    /**
     * ROLE_USER && ROLE_DBA 权限访问。
     * @return
     */
    @PreAuthorize("hasAuthority('ROLE_USER') && hasAuthority('ROLE_DBA')")
    String user2();
}

上面我们提供了6个接口,分别有@Secure和@PreAuthorize注解实现的,这两种功能上其实没有太大区别。
注意:@Secured里面添加多个权限之间是或者的关系,就是有一个权限就可以。
@PreAuthorize后面我们可以用Spring-EL表达式实现且的关系如上面的user2()接口。
@PreAuthorize更多的指定权限的方法可以到SecurityExpressionRoot里面查找。

@PreAuthorize("hasAuthority('ROLE_USER')")
public interface MethodSecureService2 {

    /**
     * 类级别的控制
     * @return
     */
    String user3();

}

这些注解处理在方法上面使用外,还可以直接在类上面使用,表示整个类的方法权限控制。

@Service
public class MethodSecureServiceImpl implements MethodSecureService {

    @Override
    public String common() {
        return "common";
    }

    @Override
    public String admin() {
        return "admin";
    }

    @Override
    public String user() {
        return "user";
    }

    @Override
    public String common2() {
        return "common2";
    }

    @Override
    public String admin2() {
        return "admin2";
    }

    @Override
    public String user2() {
        return "user2";
    }
}
@Service
public class MethodSecureService2Impl implements MethodSecureService2 {

    @Override
    public String user3() {
        return "user3";
    }
}

上面是两个接口的实现类,很简单就是返回一个字符串。

2.添加请求的接口

@RequestMapping("method")
@RestController
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class MethodSecureController {

    @Autowired
    private MethodSecureService methodSecureService;
    @Autowired
    private MethodSecureService2 methodSecureService2;

    @GetMapping("common")
    public String common() {
        return methodSecureService.common();
    }
    @GetMapping("admin")
    public String admin() {
        return methodSecureService.admin();
    }
    @GetMapping("user")
    public String user() {
        return methodSecureService.user();
    }

    @GetMapping("common2")
    public String common2() {
        return methodSecureService.common2();
    }
    @GetMapping("admin2")
    public String admin2() {
        return methodSecureService.admin2();
    }
    @GetMapping("user2")
    public String user2() {
        return methodSecureService.user2();
    }
    @GetMapping("user3")
    public String user3() {
        return methodSecureService2.user3();
    }
}

注意:
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
要开启方法级别的权限控制,需要提供上面这个注解,一般我们写在Springboot启动类上面。这里为了方便,我就直接写在这个Controller里面了。
其中securedEnabled=true是如果使用的@Secure注解的话需要加上的。
prePostEnabled = true是如果使用@PreAuthorize注解的话需要加上的。

3. 启动项目开始测试。

首先我们使用user:userpwd登陆

http://localhost:10022/security/login

然后访问

http://localhost:10022/security/method/user

发现可以访问成功,
说明:@Secure后面多个权限直接的关系是OR的关系,有一个就可以实现。

接着我们访问

http://localhost:10022/security/method/user2

发现403错误。
然后我们使用dba:dbapwd的账号密码登陆再去访问上面的user2接口。
发现可以访问。
说明:@PreAuthorize可以通过&&的Spring-EL语法实现AND的关系,必须两个权限同时满足才能访问。

其他的几个接口可以自行测试,这里就不一一介绍了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot和Spring Security是一对好朋友,Spring Boot提供了强大的自动配置和快速开发的能力,而Spring Security则提供了完整的安全解决方案,可以实现用户认证、授、安全过滤等功能。本文将介绍如何在Spring Boot中整合Spring Security实现权限控制。 1. 添加Spring Security依赖 在pom.xml文件中添加以下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ``` 2. 配置Spring SecuritySpring Boot中,可以通过application.properties或application.yml文件配置Spring Security。以下是一个简单的配置: ``` spring.security.user.name=admin spring.security.user.password=123456 spring.security.user.roles=ADMIN ``` 这个配置定义了一个用户名为admin,密码为123456,角色为ADMIN的用户。在实际应用中,应该将用户名和密码存储在数据库或其他安全存储中。 3. 创建SecurityConfig类 创建一个继承自WebSecurityConfigurerAdapter的SecurityConfig类,并重写configure方法: ``` @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/", "/home").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("admin").password("{noop}123456").roles("ADMIN"); } } ``` configure方法定义了应用程序的安全策略,这里配置了所有请求都需要认证(即登录)才能访问,除了首页和登录页,这两个页面可以匿名访问。formLogin方法配置了自定义的登录页面,logout方法配置了退出登录的操作。 configureGlobal方法定义了一个内存中的用户,用户名为admin,密码为123456,角色为ADMIN。在实际应用中,应该将用户信息存储在数据库或其他安全存储中。 4. 创建登录页面 在templates目录下创建一个名为login.html的登录页面,例如: ``` <!DOCTYPE html> <html> <head> <title>Login Page</title> </head> <body> <h1>Login Page</h1> <div th:if="${param.error}"> Invalid username and password. </div> <div th:if="${param.logout}"> You have been logged out. </div> <form th:action="@{/login}" method="post"> <div> <label>Username:</label> <input type="text" name="username" /> </div> <div> <label>Password:</label> <input type="password" name="password" /> </div> <div> <button type="submit">Login</button> </div> </form> </body> </html> ``` 5. 运行应用程序 在浏览器中访问http://localhost:8080/login,输入用户名admin和密码123456,即可登录成功。如果输入错误的用户名或密码,则会提示“Invalid username and password.”。如果成功登录后再访问http://localhost:8080/home,则可以看到“Welcome home!”的欢迎消息。 6. 实现权限控制 上面的例子中只实现了登录认证,没有实现权限控制。下面介绍如何实现权限控制。 首先需要在configureGlobal方法中添加更多的用户和角色: ``` @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("admin").password("{noop}123456").roles("ADMIN") .and() .withUser("user").password("{noop}password").roles("USER"); } ``` 这里定义了一个管理员用户和一个普通用户,分别拥有ADMIN和USER两个角色。 然后在configure方法中添加更多的安全策略: ``` @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/", "/home").permitAll() .antMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); } ``` 这里添加了一个安全策略,即/admin/**路径需要拥有ADMIN角色才能访问。 现在管理员用户可以访问/admin/**路径,而普通用户则不能访问。如果普通用户尝试访问/admin/**路径,则会提示“Access is denied”。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值