欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring Boot Security 入门—内存用户验证

程序员文章站 2023-10-29 11:20:52
简介 作为 Spring 全家桶组件之一,Spring Security 是一个提供安全机制的组件,它主要解决两个问题: 认证:验证用户名和密码; 授权:对于不同的 URL 权限不一样,只有当认证的用户拥有某个 URL 的需要的权限时才能访问。 Spring Security 底层使用的是过滤器,针 ......

简介

作为 spring 全家桶组件之一,spring security 是一个提供安全机制的组件,它主要解决两个问题:

  • 认证:验证用户名和密码;
  • 授权:对于不同的 url 权限不一样,只有当认证的用户拥有某个 url 的需要的权限时才能访问。

spring security 底层使用的是过滤器,针对 url 进行的拦截,对应到 java 中也就是类; 因此被称为粗粒度授权验证,就是验证 url ,当前用户是否有这个 url 的权限。

入门

创建项目

使用 idea 创建 spring boot 项目,勾选需要的组件:

  • spring web
  • spring security

或者创建项目后添加依赖:

<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>

这里使用的是 jsp 作为模板,有关如何在 spring boot 中使用 jsp 作为模板请访问:

websecurityconfig

package top.cloudli.demo.security;

import org.springframework.context.annotation.configuration;
import org.springframework.security.config.annotation.authentication.builders.authenticationmanagerbuilder;
import org.springframework.security.config.annotation.method.configuration.enableglobalmethodsecurity;
import org.springframework.security.config.annotation.web.builders.httpsecurity;
import org.springframework.security.config.annotation.web.configuration.enablewebsecurity;
import org.springframework.security.config.annotation.web.configuration.websecurityconfigureradapter;
import org.springframework.security.crypto.bcrypt.bcryptpasswordencoder;
import org.springframework.security.crypto.password.passwordencoder;

@configuration
@enablewebsecurity
@enableglobalmethodsecurity(prepostenabled=true)
public class securityconfig extends websecurityconfigureradapter {
    @override
    protected void configure(authenticationmanagerbuilder auth) throws exception {
        passwordencoder encoder = new bcryptpasswordencoder();
        
        auth.inmemoryauthentication()
                .passwordencoder(encoder)
                .withuser("root")
                .password(encoder.encode("root@123456"))
                .roles("root", "user")
                .and()
                .withuser("user")
                .password(encoder.encode("user@123456"))
                .roles("user");
    }

    @override
    protected void configure(httpsecurity http) throws exception {
        http.authorizerequests()
                .antmatchers("/css/**")
                .permitall()        // css 不用验证
                .anyrequest()
                .authenticated()    // 其它页面全部需要验证
                .and()
                .formlogin()        // 使用默认登录页面
                .and()
                .exceptionhandling()
                .accessdeniedpage("/401")   // 无权限时跳转的页面
                .and()
                .logout();
    }
}
  • @enablewebsecurity 注解启用验证;
  • @enableglobalmethodsecurity(prepostenabled=true) 注解允许我们在控制器的方法中使用 @preauthorize 实现权限分割。

此处创建了两个用户并保存在内存中,分别是拥有 root 和 user 权限的 root 用户和仅拥有 user 权限的 user 用户。

fromlogin() 方法可以接着调用 loginpage() 指定一个自定义登录页面,这里使用的是默认登录页面。

编写页面

1.index.jsp,所有通过验证的用户都可以访问:

<%--
  任何通过验证的用户都能访问的页面
--%>
<%@ page contenttype="text/html;charset=utf-8" language="java" %>
<html>
<head>
    <title>spring security demo application</title>
    <link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
<div class="content">
    <h1>spring security in memory authentication</h1>
    <h2>这是被保护的页面(role_user)。</h2>
</div>
</body>
</html>

2.root.jsp,只有拥有 root 权限的用户能访问:

<%--
  需要 role_root 才能访问的页面
--%>
<%@ page contenttype="text/html;charset=utf-8" language="java" %>
<html>
<head>
    <title>root page</title>
    <link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
<div class="content">
    <h1>root page</h1>
    <h2>你正在访问受保护的页面(role_root)。</h2>
</div>
</body>
</html>

3.401.jsp,没有权限时跳转的页面:

<%--
  权限不够时跳转的页面
--%>
<%@ page contenttype="text/html;charset=utf-8" language="java" %>
<html>
<head>
    <title>401 unauthorized</title>
    <link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body class="error">
<div class="content">
    <h1>401 unauthorized!</h1>
    <h2>你没有权限访问此页面。</h2>
</div>
</body>
</html>

控制器

package top.cloudli.demo.controller;

import org.springframework.security.access.prepost.preauthorize;
import org.springframework.stereotype.controller;
import org.springframework.web.bind.annotation.getmapping;

@controller
public class democontroller {

    @preauthorize("hasanyauthority('role_user')")
    @getmapping("/")
    public string index() {
        return "index";
    }

    @preauthorize("hasanyauthority('role_root')")
    @getmapping("/root")
    public string root() {
        return "root";
    }

    @getmapping("/401")
    public string accessdenied() {
        return "401";
    }
}

@preauthorize 注解指定了访问页面所需要的权限,这里的权限要加上 role_ 前缀。

run

访问 http://localhost:8080/ 将进入登录页面(这里使用的是 spring security 的默认登录页面):

Spring Boot Security 入门—内存用户验证

使用刚才创建的内存用户 user 登录后将返回 index 页面:

Spring Boot Security 入门—内存用户验证

访问 http://localhost:8080/root,由于 user 用户没有 role_root 权限,跳转到 401 页面:

Spring Boot Security 入门—内存用户验证

访问 http://localhost:8080/logout 将进入默认登出页面:

Spring Boot Security 入门—内存用户验证

这里的登录和登出页面均可以使用自定义页面,只需要在自定义的页面中把数据通过 psot 请求提交到 /login/logout 即可完成登录和登出。