SpringSecurity入门使用——资源授权

上一篇大概陈述了一下关于SpringSecurity的用户登录,从使用不同的方式进行用户登录做了一个简单的介绍。在开头我也曾提到过,SpringSecurity主要有两大功能,第一个就是用户登录,第二个就是资源授权。这篇就来大概描述一下资源授权的整个过程。

一.实现configure(HttpSecurity http)方法

在配置类中重写configure(HttpSecurity http)方法,注意参数是HTTPSecurity,在这里做一个最简单的登录成功失败Url配置。

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .successForwardUrl("/success")
                .failureForwardUrl("/fail");
    }

在Controller中新增以下几个方法,登录成功进入“home”页面,该页面有三个a标签,分别指向“admin”,“manager”,“worker”页面,在template目录下新建,home.html,fail.html,admin.html,manager.html,worker.html,子页面有跳转到home页面的连接。


   @PostMapping("/success")
    public String success(){
        return "home";
    }
    @PostMapping("/fail")
    public String fail(){
        return "fail";
    }
    @GetMapping("/admin")
    public String admin(){
        return "admin";
    }
    @GetMapping("/manager")
    public String manager(){
        return "manager";
    }
    @GetMapping("/worker")
    public String worker(){
        return "worker";
    }

    @GetMapping("/home")
    public String home(){
        return "home";
    }

运行代码,随便登录一个账号,发现只要用户名和密码输入正确,都可以访问Home页面中的任意链接。下面就对页面开始授权,只能登录账号访问已授权的页面,未授权的禁止访问。

二 方法

1.hasAuthority 方法

如果当前的主体具有指定的权限,则返回 true,否则返回 false.

在configure(HTTPSecurity http)方法中加上这句,这句话的意思就是访问“/admin”接口的用户必须拥有"admin"权限,访问“manager”的用户必须拥有“manager”权限。

        http.authorizeRequests()
                .antMatchers("/admin").hasAuthority("admin")
                .antMatchers("/manager").hasAuthority("manager")
                .antMatchers("/worker").hasAuthority("worker")
                .anyRequest() // 其他请求
                .authenticated();

当前数据库记录:

重新启动项目,发现name为“zhangsan”的用户只能访问“admin.html”,访问其他页面会报403,也就是没有当前权限。

2.hasAnyAuthority

如果当前的主体有任何提供的角色(给定的作为一个逗号分隔的字符串列表)的话,返回 true.

根据我们数据库的配置,name为“zhangsan”的用户可以访问既可以“admin.html”,也可以访问“manager.html”和“worker.htm”页面。若表示拥有多个权限,可以使用hasAnyAuthority()。

 http.authorizeRequests()
                .antMatchers("/admin").hasAnyAuthority("admin")
                .antMatchers("/manager").hasAnyAuthority("admin,manager")
                .antMatchers("/worker").hasAnyAuthority("admin,manager,worker")
                .anyRequest() // 其他请求
                .authenticated();

重启项目,发现zhangsan可以访问任意页面,lisi只能访问非admin页面,wangwu只能访问worker页面。

3.hasRole

如果用户具备给定角色就允许访问,否则出现 403。

        http.authorizeRequests()
                .antMatchers("/admin").hasRole("admin")
                .anyRequest() // 其他请求
                .authenticated();

然后我用"zhangsan"用户登录,发现跳转到了home页面,然后去访问“admin”链接时,却报了403.

查看hasRole源码发现,在权限名称的前面加了个"ROLE_",因为我在数据库中只写了指定的权限名称,没有在加"ROLE_"前缀,所以默认会没有权限访问。这个问题可以在数据库name前加上“ROLE_”,也可以修改读取权限方法,在权限名前加上“ROLE_”关键字即可。

修改读取权限集合方法,在name钱都加上“ROLE_”


    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> list = new ArrayList<>(roles.size());
        for (SysRole role : roles) {
            list.add(new SimpleGrantedAuthority("ROLE_"+role.getName()));
        }
        return list;
    }

重启项目,访问admin.html页面成功。

4.hasAnyRole

和hasAnyAuthority()用法相似,这里就不做演示了。只需要在权限间使用逗号隔开就可以了。

三.注解

1.@Secured

作用:用在接口上,用来判断接口是否具有某种角色。另外需要注意的是这里匹配的字符串需要添加前缀“ROLE_“。多个角色可用逗号隔开。

首先需要开启注解,在启动类中加上@EnableGlobalMethodSecurity(securedEnabled=true)

定义一个接口,只能由“admin”权限的人才能够进入,进入接口后返回一个字符串。

    @Secured("ROLE_admin")
    @GetMapping("secured_admin")
    @ResponseBody
    public String securedAdmin() {
        return "Secured Admin";
    }

登录“admin”账号,访问该接口,页面打印后台返回的字符串。

使用其它账号提示没有权限。

2.@PreAuthorize

作用:进入方法前的验证用户是否具有某种权限。

在启动类中加上@EnableGlobalMethodSecurity(prePostEnabled = true)开启注解。

定义一个方法,具有“manager”权限的人才能进入该方法。

    @PreAuthorize("hasAnyRole('manager')")
    @GetMapping("pre_authorize")
    @ResponseBody
    public String preAuthorize() {
        return "PreAuthorize Manager";
    }

测试结果略。 

3.@PostAuthorize

作用:在方法执行后进行权限验证。

在启动类中加入@EnableGlobalMethodSecurity(prePostEnabled= true)开启注解。

定义一个方法,只有具有“admin”权限的人才能进入,然后在该方法中做一个打印语句。

    @PostAuthorize("hasAnyRole('admin')")
    @GetMapping("post_authorize")
    @ResponseBody
    public String PostAuthorize() {
        System.out.println("entry method");
        return "PostAuthorize Admin";
    }

登录没有“admin”权限的账号,尝试进入该方法,页面报403没有权限,查看idea控制台发现,打印语句执行。由此可以证明该注解是先进入方法,执行完成后才会验证是否拥有权限。

4.@PostFilter

作用:权限验证之后对数据进行过滤

定义一个方法,返回一个User对象list,然后对该List进行数据过滤,只返回name为"admin"的对象。

定义User对象

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Long id;
    private String name;
    private String roleName;
}

定义方法,构造List,在里面添加三条数据。在方法上使用@PostFilter注解,仅返回name为“admin”的数据。

    @Secured("ROLE_admin")
    @GetMapping("post_filter")
    @PostFilter("filterObject.name == 'admin'")
    @ResponseBody
    public List<User> postFilter() {
        ArrayList<User> list = new ArrayList<>(3);
        list.add(new User(1L, "admin", "admin"));
        list.add(new User(2L, "manager", "manager"));
        list.add(new User(3L, "worker", "worker"));
        return list;
    }

调用该方法,返回结果如下:

5.@PreFilter

作用:进入控制器之前对数据进行过滤。

往后台传一个list,并返回id为偶数的对象,过滤id为基数的对象。

定义一个接口,并使用@PreFilter过滤对象id。将过滤后的id在控制台打印。

    @Secured("ROLE_admin")
    @GetMapping("pre_filter")
    @PreFilter("filterObject.id%2==0")
    @ResponseBody
    public List<User> preFilter(@RequestBody List<User> list) {
        list.forEach(e -> System.out.println(e.getId()));
        return list;
    }

使用PostMan进行方法调用,传入一个对象list,里面有四个对象,id分别为1,2,3,4。 

控制台打印结果:

后台返回数据:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Security是一个用于身份验证和授权的框架,在Spring项目中提供了一套强大的安全性解决方案。以下是你入门Spring Security的步骤: 1. 添加Spring Security依赖:在你的项目中,通过Maven或Gradle添加Spring Security的依赖。例如,在Maven中,你可以添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ``` 2. 配置Spring Security:创建一个配置类来配置Spring Security。这个配置类需要继承`WebSecurityConfigurerAdapter`类,并覆盖`configure`方法。例如,你可以创建一个类叫做`SecurityConfig`: ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/public/**").permitAll() // 允许公共访问的URL .anyRequest().authenticated() // 其他URL需要身份验证 .and() .formLogin() // 启用表单登录 .loginPage("/login") // 自定义登录页面URL .permitAll() .and() .logout() // 启用注销 .permitAll(); } } ``` 上述配置中,我们定义了哪些URL是公开访问的,哪些URL需要身份验证,以及自定义了登录和注销的相关配置。 3. 创建用户服务:在上面的配置类中,你需要定义一个用户服务来获取用户的身份验证信息。这可以通过实现`UserDetailsService`接口来完成。你可以创建一个类叫做`UserService`来实现这个接口,并重写`loadUserByUsername`方法: ```java @Service public class UserService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 从数据库或其他数据源中获取用户信息 // 然后返回一个实现了UserDetails接口的类,代表用户的身份验证信息 // 例如,你可以使用Spring Security提供的User类 return User.builder() .username(username) .password("password") .roles("USER") .build(); } } ``` 上述代码中,我们简单地返回了一个固定的用户信息,实际应用中你需要从数据库或其他数据源中获取真实的用户信息。 4. 配置密码编码器:为了安全起见,你需要对用户密码进行编码。在上述的配置类中,通过重写`configure`方法来配置密码编码器。例如: ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserService userService; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userService).passwordEncoder(passwordEncoder()); } // 其他配置... } ``` 上述代码中,我们使用了`BCryptPasswordEncoder`来对密码进行编码。 这些是入门Spring Security的基本步骤。当你完成了上述配置后,你的应用程序将需要进行身份验证,并且可以通过URL保护来限制访问。你可以根据需要进一步自定义和扩展Spring Security的功能。希望这能帮助到你!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值