SpringSecurity框架学习与使用

这篇具有很好参考价值的文章主要介绍了SpringSecurity框架学习与使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

SpringSecurity学习

SpringSecurity入门

引入相关的依赖,SpringBoot的版本是2.7.10;

        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity6</artifactId>
            <version>3.1.1.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

前端页面编写,home.html、hello.html、login.html

hello.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity6">
<head>
    <title>Hello World!</title>
</head>
<body>
<h1 th:inline="text">Hello <span th:remove="tag" sec:authentication="name">thymeleaf</span>!</h1>
<form th:action="@{/logout}" method="post">
    <input type="submit" value="Sign Out"/>
</form>
</body>
</html>

home.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<head>
    <title>Spring Security Example</title>
</head>
<body>
<h1>Welcome!</h1>

<p>Click <a th:href="@{/templates/hello.html}">here</a> to see a greeting.</p>
</body>
</html>

login.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<head>
    <title>Spring Security Example </title>
</head>
<body>
<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> User Name : <input type="text" name="username"/> </label></div>
    <div><label> Password: <input type="password" name="password"/> </label></div>
    <div><input type="submit" value="Sign In"/></div>
</form>
</body>
</html>

视图控制,访问对应的url跳转到不同的页面

/**
 * 视图配置
 */
@Configuration
public class MvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        WebMvcConfigurer.super.addViewControllers(registry);
        //请求/home时显示home.html页面
        registry.addViewController("/home").setViewName("home");
        registry.addViewController("/").setViewName("home");
        registry.addViewController("/hello").setViewName("hello");
        registry.addViewController("/login").setViewName("login");
    }
}

SpringSecurity配置

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(request -> {
                    request.antMatchers("/").permitAll()
		                    // /home、/  的请求可以访问
                            .antMatchers("/home").permitAll() 
                            //除了上面的请求,其它的请求必须认证通过
                            .anyRequest().authenticated();  
                })
                //设置登录页面以及允许访问登录页面,springSecurity是有自带的默认登录页面的,如果不		      	设置会跳转到默认的登录页面
                .formLogin((form) -> form.loginPage("/login").permitAll())  
                //允许访问登出页面
                .logout(LogoutConfigurer::permitAll);
        return http.build();
    }

	 /**
     * 设置默认的登录密码,这里是直接使用存放在内存中的密码;
     * 实际开发从数据库中查询读取
     * @return
     */
    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder()
                .username("user")
                .password("password")
                .roles("USER")
                .build();
        return new InMemoryUserDetailsManager(user);
    }
}

结果
SpringSecurity框架学习与使用
登录失败时
SpringSecurity框架学习与使用
登录成功
SpringSecurity框架学习与使用

SpringSecurity深入

认证

上面的demo中,我们是把登录密码放在内存中记录着的,除了这种方式外我们还可以在配置文件中设置登录用户名和密码;
SpringSecurity框架学习与使用
实际开发中一般都从数据库中进行读取;因此我们需要实现UserDetailsService接口,这个接口中有一个loadUserByUsername方法,我们在这个方法中根据username查询用户的信息,如果查询到了,就把用户的信息封装成UserDetails返回。
SpringSecurity框架学习与使用

用户输入的密码会被我们注入的PasswordEncoder加密,所以在后面模拟的从数据库中查询用户密码的时候,对输入的密码使用PasswordEncoder加密了。

    /**
     * 密码加密
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

用户认证接口实现

@Service("userDetailService")
public class MyUserDetailServiceImpl implements UserDetailsService {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //模拟从数据库中查询出密码
        if ("zhangsan".equals(username)) {
            username = "zhangsan";
            String password = passwordEncoder.encode("root");
            return new User(username, password, true, true, true, true,
                    AuthorityUtils.commaSeparatedStringToAuthorityList("admin, ROLE_SALES"));
        }
        throw new UsernameNotFoundException("用户没有找到");
    }
    
}

授权

前面我们对用户认证进行了讲解,接下来讲如何授权。
在SpringSecurity中用户认证和授权的过程是很紧密的,在loadUserByUsername方法返回的UserDetails的构造函数中最后一个参数就是用户具有的权限。而在Shiro中,授权和认证是分为两个方法的。

在SpringSecurity中我们通过AuthorizedUrl类的方法来确定访问指定的url需要的请求和角色。

方法 作用
hasAuthority 如果当前的主体具有指定的权限,则返回 true,否则返回 false
hasAnyAuthority 如果当前的主体有任何提供的角色(给定的作为一个逗号分隔的字符串列表)的话,返回true
hasRole 如果用户具备给定角色就允许访问,否则出现 403。如果当前主体具有指定的角色,则返回 true
hasAnyRole 表示用户具备任何一个条件都可以访问

SpringSecurity框架学习与使用
url:/test/test1,只有SALES角色才能访问;
url:/test/test2,只有admin权限才能访问;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(request -> {
                    request.antMatchers("/").permitAll()
                            .antMatchers("/home").permitAll() // /home、/  的请求可以访问
                            //需要SALES角色才可以访问
                            .antMatchers("/test/test1").hasRole("SALES")
                            //需要admin权限才能访问
                            .antMatchers("/test/test2").hasAuthority("admin")
                            .anyRequest().authenticated();  //除了上面的,其它的请求必须认证通过
                })
                .formLogin((form) -> form.loginPage("/login").permitAll())  //设置登录页面以及允许访问登录页面
                .logout(LogoutConfigurer::permitAll);
        return http.build();
    }

自定义授权失败页面

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(request -> {
            request.antMatchers("/").permitAll()
                    .antMatchers("/home").permitAll() // /home、/  的请求可以访问
                    .antMatchers("/test/test1").hasRole("SALES")
                    .antMatchers("/test/test2").hasAuthority("admin")
                    .anyRequest().authenticated();  //除了上面的,其它的请求必须认证通过
        });
        //设置没有权限访问跳转自定义页面
        http.exceptionHandling().accessDeniedPage("/error.html");
        http.formLogin((form) -> {
                    //设置登录页面以及允许访问登录页面
                    form.loginPage("/login").permitAll()
                            //登录访问路径
                            .loginProcessingUrl("/login")
                            //登录成功之后的跳转路径
                            .defaultSuccessUrl("/hello").permitAll(); 
                })
                .logout(LogoutConfigurer::permitAll);
        return http.build();
    }

权限注解

注解 作用
@Secured 判断是否具有角色,另外需要注意的是这里匹配的字符串需要添加前缀“ROLE_
@PreAuthorize 注解适合进入方法前的权限验证, @PreAuthorize 可以将登录用户的 roles/permissions 参数传到方法中
@PostAuthorize 在方法执行后再进行权限验证,适合验证带有返回值的权限
@PostFilter 权限验证之后对数据进行过滤 留下用户名是 admin1 的数据
@Secured

@Secured:判断是否具有角色,另外需要注意的是这里匹配的字符串需要添加前缀“ROLE_“
使用@Secured注解之前需要先使用注解@EnableGlobalMethodSecurity(securedEnabled=true)开启此功能;

@RequestMapping("testSecured")
@ResponseBody
@Secured({"ROLE_normal","ROLE_admin"}) //判断是否有normal、admin角色
public String helloUser() {
return "hello,user";
}
@PreAuthorize

@PreAuthorize:注解适合进入方法前的权限验证, @PreAuthorize 可以将登录用户的 roles/permissions 参数传到方法中;同样的使用之前也需要使用@EnableGlobalMethodSecurity(prePostEnabled = true)开启此功能;

@RequestMapping("/preAuthorize")
@ResponseBody
@PreAuthorize("hasAnyAuthority('menu:system')")
public String preAuthorize(){
 System.out.println("preAuthorize");
return "preAuthorize";
}
@PostAuthorize

@PostAuthorize:在方法执行后再进行权限验证,适合验证带有返回值的权限;

@RequestMapping("/testPostAuthorize")
@ResponseBody
@PostAuthorize("hasAnyAuthority('menu:system')")
public String preAuthorize(){
System.out.println("test--PostAuthorize");
return "PostAuthorize";
}
@PostFilter

@PostFilter :权限验证之后对数据进行过滤 留下用户名是 admin1 的数据;
表达式中的 filterObject 引用的是方法返回值 List 中的某一个元素;

@RequestMapping("getAll")
@PreAuthorize("hasRole('ROLE_管理员')")
@PostFilter("filterObject.username == 'admin1'")
@ResponseBody
public List<UserInfo> getAllUser(){
 ArrayList<UserInfo> list = new ArrayList<>();
 list.add(new UserInfo(1l,"admin1","6666"));
 list.add(new UserInfo(2l,"admin2","888"));
return list;
}
@PreFilter

@PreFilter: 进入控制器之前对数据进行过滤

@RequestMapping("getTestPreFilter")
@PreAuthorize("hasRole('ROLE_管理员')")
@PreFilter(value = "filterObject.id%2==0")
@ResponseBody
public List<UserInfo> getTestPreFilter(@RequestBody List<UserInfo>
list){
 list.forEach(t-> {
 System.out.println(t.getId()+"\t"+t.getUsername());
 });
return list;
}

除了上面提到的注解外,还有权限表达式,权限表达式文章来源地址https://www.toymoban.com/news/detail-434232.html

参考

  1. SpringSecurity视频
  2. SpringSecurity教程
  3. SpringSecurity文档

到了这里,关于SpringSecurity框架学习与使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringSecurity 安全框架详解

    先赘述一下身份认证和用户授权: 用户认证( Authentication ):系统通过校验用户提供的用户名和密码来验证该用户是否为系统中的合法主体,即是否可以访问该系统; 用户授权( Authorization ):系统为用户分配不同的角色,以获取对应的权限,即验证该用户是否有权限执行

    2024年02月02日
    浏览(40)
  • 【Java-框架-SpringSecurity】随笔

    项目文件; 【1】 【2】 【3】 【4】 【5】 【6】 【7】

    2024年01月18日
    浏览(42)
  • SpringBoot集成 SpringSecurity安全框架

    提示:以下是本篇文章正文内容,Java 系列学习将会持续更新 我们时常会在 QQ 上收到别人发送的钓鱼网站链接,只要你在登录QQ账号的情况下点击链接,那么不出意外,你的号已经在别人手中了。实际上这一类网站都属于 恶意网站 ,专门用于盗取他人信息,执行非法操作,

    2024年02月07日
    浏览(48)
  • SpringSecurity分布式安全框架

    Spring Security是一个基于Spring框架的安全框架,它提供了全面的安全解决方案,包括用户认证和用户授权等Web应用安全性问题。Spring Security可以轻松扩展以满足自定义需求,它的真正强大之处在于它可以轻松扩展以满足自定义要求。 对于分布式系统来说,Spring Security可以结合

    2024年02月08日
    浏览(47)
  • SpringSecurity安全框架 ——认证与授权

    目录  一、简介 1.1 什么是Spring Security 1.2 工作原理 1.3 为什么选择Spring Security 1.4 HttpSecurity 介绍🌟 二、用户认证 2.1 导入依赖与配置 2.2 用户对象UserDetails 2.3 业务对象UserDetailsService 2.4 SecurityConfig配置 2.4.1 BCryptPasswordEncoder密码编码器 2.4.2 RememberMe 记住登录信息 2.4.3 CSR

    2024年02月04日
    浏览(42)
  • SpringSecurity源码分析(一) SpringBoot集成SpringSecurity即Spring安全框架的加载过程

          Spring Security是一个强大的并且高度可定制化的访问控制框架。 它基于spring应用。 Spring Security是聚焦于为java应用提供授权和验证的框架。像所有的spring项目一样,Spring Security真正的强大在于可以非常简单的拓展功能来实现自定义的需求。       在分析SpringBoot集成的Sp

    2024年02月03日
    浏览(44)
  • SpringSecurity学习(八)OAuth2.0、授权服务器、资源服务器、JWT令牌的使用

    OAuth2是一个认证协议,SpringSecurity对OAuth2协议提供了响应的支持,开发者可以非常方便的使用OAuth2协议。 简介 四种授权模式 Spring Security OAuth2 GitHub授权登录 授权服务器与资源服务器 使用JWT OAuth是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密资源

    2024年02月02日
    浏览(56)
  • SpringSecurity框架快速搭建(SpringBoot整合Security)

    目录 Common类 Config类 CorsConfig(解决跨域问题) RedisConfig (Redis数据库配置) Spring Security (配置安全功能的类) expression类(Expression 类通常用于权限控制和安全策略的定义) SGExpressionRoot(判断用户是否具有某个权限) Filter类 JwtAuthenticationTokenFilter(解析token看是否放行) Handler类

    2024年02月09日
    浏览(42)
  • SpringSecurity源码学习四:会话管理

    会话管理是指在Java应用程序中管理用户会话状态的过程。在Spring框架中,可以使用Spring Session来实现会话管理。Spring Session提供了一种机制,用于在不同的会话存储后端(例如内存、数据库、Redis等)中存储和管理会话数据。 通过使用Spring Session,您可以轻松地在Spring应用程序

    2024年02月08日
    浏览(33)
  • WebSocket和SpringSecurity的学习记录

    1. WebSocket 基础概念 什么是 WebSocket? WebSocket 是一种网络通信协议,提供了在单个 TCP 连接上进行全双工通信的方式。\\\"全双工\\\"意味着客户端和服务器可以同时发送和接收信息,这与传统的 HTTP 请求不同,后者是一种半双工通信方式(即一次只能进行一个请求或响应)。 WebSock

    2024年01月21日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包