Spring Security快速入门

1.什么是Spring Security

        Spring SecuritySpring Security是目前Java Web领域中最流行的框架之一,它提供了一系列安全级别,包括基于认证和授权的安全保护,以及各种各样的安全校验,使得开发人员可以非常容易地为应用程序添加安全保护。Spring Security也提供了一种简单易用的方式来定制其过滤器链,以适应具体的安全需求。

      (1)在用户认证方面,Spring Security 框架支持主流的认证方式,包括 HTTP 基本认证、HTTP 表单验证、HTTP 摘要认证、OpenIDLDAP 等。

      (2)在用户授权方面,Spring Security 提供了基于角色的访问控制和访问控制列表(Access Control List,ACL),可以对应用中的领域对象进行细粒度的控制。

2.工作原理和特点

原理:

        认证:认证模块负责验证用户身份的合法性,生成认证令牌,并保存到服务端会话中(如TLS)。

        鉴权:鉴权模块负责从服务端会话内获取用户身份信息,与访问的资源进行权限比对。

特点:

  1. 兼容性强Spring Security是一个流行的开源框架,它可以与Spring应用程序完美集成。由于它的兼容性很好,因此可以非常方便地使用它保护Web应用程序。

  2. 功能强大Spring Security具备众多功能,包括注销、登录、角色、权限、令牌、XSS防御、CSRF防御等等。它还支持各种身份验证、角色和权限管理方式,如基于表单的认证、基于记住我功能的认证以及OAuth认证等等。

  3. 安全可靠Spring Security具有极高的安全性,它使用最新的安全标准和协议来保护Web应用程序。Spring Security采用安全性分层的策略来保护应用程序中的各个层,例如Web层、Service层、DAO层等等。除此之外,Spring Security还支持自定义安全策略和事件响应,从而使得开发者可以根据应用程序需求定制安全保护。

  4. 易于使用Spring Security提供了一种高度简化的方式来保护Web应用程序。它使用简单的标签和安全注解来添加安全保护,从而使得开发者可以基本不需要手动编写代码就可以完成安全保护。

  5. 社区广泛Spring Security是一个著名的开源框架,因此它有一个庞大的用户社区。这个社区不仅提供了大量的文档、示例和教程,而且还会解答开发者的问题、修复框架中的BUG等等。这为开发者提供了无限的支持和帮助,从而可以使用Spring Security更加自信。

3.代码实战入门 

    1.基于springboot创建项目 

        (1)导入依赖

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>

(2)配置yml文件

spring:
    freemarker:
        suffix: .ftl
        template-loader-path: classpath:/templates/
        enabled: true

(3)创建控制类,定义请求处理方法

@Controller
public class HelloController {

    @RequestMapping("/hello")
    public String hello(){
       return "hello,spring security";
    }
}

(4)启动项目,系统会自动生成一个默认的随机登录密码(因为当前没有配置用户信息,配置之后就不会在生成默认登录密码)

 注:这是 Spring Security 为默认用户 user 生成的临时密码,是一个 UUID 字符串

(5)访问登录页并进行测试

 

(6)在yml文件中配置自定义用户名和密码。  

spring:
  security:
    user:
      name: admin
      password: 123456

配置成功后,重启服务并进行测试

4.实现自定义的登录

     1.自定义一个登录页面
<h1>用户登录</h1>
<form action="/userLogin" method="post">
    <label>用户:</label><input type="text" name="username"/><br/>
    <label>密码:</label><input type="password" name="password"/><br/>
    <input type="submit" value="登录"/>
</form>

     主页:

<body>
<h1>Welcome</h1>
<h2>Spring Security</h2>
<div style="position: absolute;top:15px;right:15px;">
    <a href="/toLogin">用户登录</a>
    <a href="/logout" onclick="return confirm('确认退出吗?');">安全退出</a>
</div>
<h4>管理员</h4>
<ul>
    <li><a href="/admin/toAddUser">新增用户</a></li>
    <li><a href="/admin/toListUser">用户列表</a></li>
    <li><a href="/admin/toResetPwd">重置密码</a></li>
    <li><a href="/admin/toUpdateUser">修改用户</a></li>
</ul>
<ul>
    <h4>普通用户</h4>
    <li><a href="/user/toUpdatePwd">修改密码</a></li>
</ul>
</body>

 

      2.创建控制层

@Controller
public class UserController {

    @RequestMapping("/toLogin")
    public String toLogin(){
        return "login";
    }

    @RequestMapping("/userLogin")
    public String userLogin(String username,String password){
        System.out.println("username="+username+",password="+password);
        return "index";
    }

    @RequestMapping("/admin/toAddUser")
    public String toAddUser(){
        return "admin/addUser";
    }

    @RequestMapping("/admin/toListUser")
    public String toListUser(){
        return "admin/listUser";
    }

    @RequestMapping("/admin/toResetPwd")
    public String toResetPwd(){
        return "admin/resetPwd";
    }

    @RequestMapping("/admin/toUpdateUser")
    public String toUpdateUser(){
        return "admin/updateUser";
    }

    @RequestMapping("/user/toUpdatePwd")
    public String toUpdatePwd(){
        return "user/updatePwd";
    }
}

3.创建配置类

进行一个自定义登录的配置之后加入一个Spring Security的安全退出设置,然后可以配置多用户角色的访问,通过修改SecurityConfig配置类,可以实现多用户的角色配置,再配置一个自定义异常处理器,设置不同角色的访问权限 

注:在配置多用户角色访问的时候需要删除或注释yml文件中配置的自定义用户名和密码 

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

    @Bean
    public PasswordEncoder bcryptPasswordEncoder() {
	    return new BCryptPasswordEncoder();
    }
    //多用户角色配置  注意:此处采用的是基于内存方式储存身份和授权信息。
    @Bean
    public UserDetailsService userDetailsService(){
        UserDetails admin = User.withUsername("admin")
        	.password(bcryptPasswordEncoder().encode("123456"))
           	.roles("ADMIN", "USER").build();
        UserDetails user = User.withUsername("user")
        	.password(bcryptPasswordEncoder().encode("123456"))
        	.roles("USER").build();
        return new InMemoryUserDetailsManager(admin,user);
    }
   
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 开放接口访问权限,不需要登录授权就可以访问
                .antMatchers("/hello","/","/toLogin").permitAll()
                // 设置角色权限
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/user/**").hasAnyRole("ADMIN","USER")
                // 其余所有请求全部需要鉴权认证
                .anyRequest().authenticated()
                .and()
                .formLogin()
                // 设置登录页面的 URL
                .loginPage("/toLogin")
                // 设置登录请求的 URL,即表单提交的 URL
                .loginProcessingUrl("/userLogin")
                // 设置登录表单中用户名字段的参数名,默认为username
                .usernameParameter("username")
                // 设置登录表单中密码字段的参数名,默认为password
                .passwordParameter("password")
                .and()
                .logout()
                 // 设置安全退出的URL路径
                .logoutUrl("/logout")
                // 设置退出成功后跳转的路径
                .logoutSuccessUrl("/");
        //添加关闭`csrf`配置
        http.csrf().disable();
        return http.build();
    }

没有访问权限的页面

<body>
<h1>未授权的操作</h1>
<div>
    未授权的操作,请与管理员联系,或切换账号重新
    <a href="/logout" onclick="return confirm('确认退出吗?');">登录</a>
    后再试!
</div>
</body>

异常说明:

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"

解决方案:这个错误通常是因为在使用 Spring Security 进行密码验证时没有正确地配置密码编码器。在 Spring Security 中,密码编码器用于将用户提供的密码编码为安全的散列值,并将其与存储在数据库中的散列值进行比较。如果没有正确地配置密码编码器,则 Spring Security 将无法识别密码编码器的类型,并在比较密码时引发“没有映射到 id“null”的密码编码器”异常。要解决这个问题,需要在 Spring Security 配置中配置一个密码编码器,并将其用于验证用户提供的密码。常用的密码编码器有 BCryptPasswordEncoderStandardPasswordEncoder

最后通过切换不同的用户(useradmin)来测试角色权限是否授权成功,admin账号访问所有接口权限正常;切换到user账号访问时,发现以/admin/**开头的接口不能访问(证明鉴权成功),但是却提示403错误。

解决方案:配置自定义异常处理器

修改SecurityConfig配置类,添加自定义异常处理,并设置异常处理页面

http.exceptionHandling().accessDeniedPage("/noauth")

重启项目后发现无权限将跳转到自定义异常页面。

  • 20
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值