Spring Seurity入门篇

Spring Seurity简介

Spring Security是一个高度自定义的安全框架。利用Spring IOC/DI和AOP功能,为系统提供了声明式安全访问控制功能,减少了为系统安全而编写大量重复代码的工作。使用Spring Security的原因有很多,但大部分都是发现了javaEE的Servlet规范或EJB规范中的安全功能缺乏典型企业应用场景。同时认识到它们在WAR或EAR级别无法移植,因此如果你更换服务器环境,还有大量工作去重新配置你的应用程序。使用Spring Security解决了这些问题,也为你提供许多其他有用的、可定制的安全功能。正如你可能知道的两个应用程序的两个主要区域是认证和授权(或者访问控制)。这两点也是Spring Security重要核心功能。"认证"是建立一个它声明的主体的过程(一个主体一般是指用户、设备或一些可以在你的应用程序中执行动作的其他系统),通俗点说就是系统认为用户是否能登录。"授权"指确定一个主体是否允许在你的应用程序执行一个动作的过程、通俗点讲就是系统判断用户是否有权限去做某些事情。

使用IDEA创建一个Demo

这里主要是记下自己自学spring security的过程,免得以后自己忘记了。这篇文章只适合对spring security什么都不知道的小白看。比如我自己,哈哈。文章很长,需要花点耐心和时间看,最好一步一步往下看,不要跳着看。
这里主要是用IDEA创建项目。创建过程如下:
第一步:
在这里插入图片描述
然后直接点击Next下一步,填好自己的项目信息:
在这里插入图片描述
然后再直接点击Next下一步,勾选下面二项:
在这里插入图片描述
在这里插入图片描述
然后直接Next,点击Finish即可
在这里插入图片描述
然后点击IDEA左上角的File选择Settings将Mavne仓库改为自己的。
在这里插入图片描述
pom.xml依赖如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.hjl</groupId>
    <artifactId>springsecurity-demo2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springsecurity-demo2</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--Spring Security组件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!--Web组件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--test组件 如果需要用Junit来测试,需要下面组件-->
        <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>
    </dependencies>

    <build>
        <!--项目打包需要的组件-->
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

到这里创建项目就完成了。

UserDetailsService作用

先在static文件夹创建一个login.html页面和main.html页面:
login.html页面内容
在这里插入图片描述
main.html页面内容:
在这里插入图片描述
然后创建一个controller文件夹和LoginController,如下:
在这里插入图片描述
然后直接启动项目,如下:
注意:每次重启项目这个密码都会改变。
在这里插入图片描述
然后在谷歌浏览器输入http://localhost:8080/login.html,它会自动来到Spring Security给的一个它自己内置的默认登录页面。如下:
Username用户名默认是user,Password是控制台打印出的那一串密码
在这里插入图片描述
看到这个页面说明spring security已经生效了。
输入用户名和后台给的密码后,就来到了我们自己写的登录页面,如下:
在这里插入图片描述
这个登录逻辑默认就是使用的Spring Security里面的UserDetailsService接口里面的loadUserByUsername方法。
在IDEA界面使用快捷键,连续按两下Shift键,查看UserDetailsService接口.
在这里插入图片描述

在这里插入图片描述
然后我们再看loadUserByUsername返回的UserDetails接口,如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
UserDetails的实现源码我就不展示了,感兴趣的小伙伴可以自己去看看。

PasswordEncoder作用

在实际使用UserDetailsService接口里面的loadUserByUsername方法时,前端将username用户名传给这个方法后会去会去数据库去查看这个user是否存在,如果不存在则会抛出用户不存在异常,如果存在就就要去比对数据库密码是否和前端传递的密码是否一样,Spring Security里面的PasswordEncoder就是用来比较密码是否一致的处理接口。
PasswordEncoder接口里面方法说明:
在这里插入图片描述
PasswordEncoder接口实现类请看BCryptPasswordEncoder类
在这里插入图片描述
选择BCryptPasswordEncoder,这里源码感兴趣可以自己去看看。
BCryptPasswordEncoder是Spring Security官方推荐的密码解析器
在这里插入图片描述
测试样例:
在这里插入图片描述

自定义登录逻辑

在项目中创建一个config文件夹,然后创建一个SecurityConfig类。内容如下:
在这里插入图片描述
然后在创建一个service文件夹,里面在创建一个impl文件夹,然后在该文件夹里面创建一个UserDetailsServiceImpl类,用来实现UserDetailsService接口,重写里面的loadUserByUsername方法。
在这里插入图片描述
UserDetailsServiceImpl类代码如下:

package com.hjl.springsecuritydemo2.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //这里因为是入门所以不使用数据库,直接先写死代码
        //1.根据用户名去数据库查询,如果不存在,抛UsernameNotFoundException异常
        //这里先写死 如果用户名不为admin
        if(!"admin".equals(username)){
            throw new UsernameNotFoundException("用户不存在!");
        }
        //2.比较密码(注册时密码是已经加密过),如果匹配成功返回UserDetails
        //通过用户名查找密码后,这里是直接用matches方法来进行比较的,因为没有连数据库,所以按如下操作
        String password=passwordEncoder.encode("123");//先将密码123进行加密
        //这里的User是security自带的User类,commaSeparatedStringToAuthorityList这是一个权限集合
        return new User(username,password, AuthorityUtils.commaSeparatedStringToAuthorityList("admin,normal"));//如果要多个权限用逗号分隔,一个的话直接写admin
    }
}


写完后我们重新启动一下,发现后台控制台没有打印出Spring Security的密码串了,如果没有看到,说明自定义逻辑成功了。也可以理解为UserDetailsServiceImpl 去实现UserDetailsService接口可以去掉后台Spring Security给的的密码串,换成自己刚刚设置的密码。用户名为admin,密码为123的用户。
在这里插入图片描述
然后在谷歌浏览器上http://localhost:8080/login.html,它会自动跳转到spring security自带的登录页面,然后我们输入刚刚在UserDetailsServiceImpl 里面写的用户名和密码进行登录验证。
在这里插入图片描述
点击登录后会再次来到自己的登录页面:
在这里插入图片描述
实际开发中肯定不是先登录spring security给的页面,然后在登我们自己写的登录页面,这样不符合业务,肯定是直接返回的就是我们自己写的登录页面。下面自定义登录页面就是来解决这个问题的。

自定义登录页面

先在SpringSecurity类里面继承WebSecurityConfigurerAdapter,然后使用快捷键ctrl+o选择configure(HttpSecurity http)重写这个方法,代码如下:

package com.hjl.springsecuritydemo2.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * Security配置类
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    //将PasswordEncoder交给spring管理
    @Bean
    public PasswordEncoder getPw(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //表单提交
        http.formLogin()
                //自定义登录页面
                .loginPage("/login.html");
    }
}

写完后重启项目,然后在谷歌浏览器输入http://localhost:8080/login.html发现可以直接来到这个页面了,不需要再去先跳转到spring security自带的登录页面进行登录后才来到自己的登录页面,也就是说这一步去掉了spring security自带的登录页面,换成了自己的登录页面。
虽然这样写ok了,但是直接访问main.html页面时,http://localhost:8080/main.html发现也可以直接访问,一般这个页面肯定是要登陆成功后才能访问的,所以还需要在SpringSecurity中添加一些限制,让页面必须在登录后才能访问。

在SpringSecurity加入如下代码,就可以解决main.html页面必须登录后才能访问到。

package com.hjl.springsecuritydemo2.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * Security配置类
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    //将PasswordEncoder交给spring管理
    @Bean
    public PasswordEncoder getPw(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //表单提交
        http.formLogin()
                //自定义登录页面
                .loginPage("/login.html");

        //授权 .anyRequest() 是拦截所有的请求 .antMatchers()是放行请求
        http.authorizeRequests()
                //放行login.html页面,login.html不需要认证,不加这个登录页面也会被拦截访问不了
                .antMatchers("/login.html").permitAll()
                //所有的请求都必须认证后才能访问,也就是说必须登录 这样就避免可以直接访问main.html页面了
                .anyRequest().authenticated();
    }
}

但是这样当你点击自己页面的登录按钮后,会发现还是在自己的登录页面,并没有跳转到main.html页面。

加入下面代码,解决登录问题。

package com.hjl.springsecuritydemo2.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * Security配置类
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    //将PasswordEncoder交给spring管理
    @Bean
    public PasswordEncoder getPw(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //表单提交
        http.formLogin()
                //自定义登录页面
                .loginPage("/login.html")
                //必须要和表单提交的接口一样,也就是form表单action里面的值,这里会走自己自定义的登录逻辑
                .loginProcessingUrl("/login") //这里的/login接口本人猜想应该是spring security自带的一个登录接口,因为自己并没有写/login接口
                //登录成功后,需要跳转到的页面,必须是POST请求,/toMain是LoginController里面的方法
                .successForwardUrl("/toMain");


        //授权 .anyRequest() 是拦截所有的请求 .antMatchers()是放行请求
        http.authorizeRequests()
                //放行login.html页面,login.html不需要认证,不加这个登录页面也会被拦截访问不了
                .antMatchers("/login.html").permitAll()
                //所有的请求都必须认证后才能访问,也就是说必须登录 这样就避免可以直接访问main.html页面了
                .anyRequest().authenticated();

        //关闭csrf csrf意思是跨站请求伪造 不然403 跨域问题
        http.csrf().disable();
    }
}

然后在LoginController里面将原来的login方法改为toMain方法,代码如下:

package com.hjl.springsecuritydemo2.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class LoginController {
    /**
     * 登录方法
     * @return
     */
    @RequestMapping(value = "/toMain",method = RequestMethod.POST)
    public String toMain(){
        return "redirect:main.html";
    }
}

然后重启项目,输入http://localhost:8080/login.html后
输入用户名:admin,密码:123后发现成功跳转到main.html页面
在这里插入图片描述
既然有成功页面,那么肯定有登录失败的页面。
创建一个error.html页面,如下:
在这里插入图片描述
然后在LoginController和SecurityConfig里面添加登录失败跳转,代码如下:
先在LoginController里面添加登录失败方法
在这里插入图片描述
然后在SecurityConfig添加如下代码:
在这里插入图片描述

然后我们重启后,在重新在浏览器访问http://localhost:8080/login.html,故意将用户名或者密码输错,如下:
在这里插入图片描述

在这里插入图片描述
如果需要放行静态资源,可如下写:
在这里插入图片描述

自定义登录成功处理器和自定义登录失败处理器

注意:登录页面中用户名和密码参数问题
在这里插入图片描述
如果登录页面的用户名请求参数不是username或者密码参数不是password的话,解决方法就是在SecurityConfig添加如下代码来接收你改过的用户名和密码的参数值如下:
在这里插入图片描述

为什么要这么做呢,因为在你登录的时候会先去Spring Security里面的 UsernamePasswordAuthenticationFilter这个过滤器里面进行过滤,里面默认的用户名是username,密码是password,请求方式是post方式,如下:
在这里插入图片描述
为什么需要自定义逻辑呢?因为实际开发有的项目是前后端分离,它跳转的肯定是前端的页面,所以要自定义逻辑处理。

自定义登录成功处理器

在项目中创建一个handler文件夹,然后在该文件夹中创建一个MyAuthenticationSuccessHandler类,用来自定义登录成功处理。
在这里插入图片描述
代码如下:

package com.hjl.springsecuritydemo2.handler;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

//自定义登录成功处理逻辑,用于前后端分离
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    private String url;

    public MyAuthenticationSuccessHandler(String url){
        this.url=url;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        System.out.println(httpServletRequest.getRemoteAddr());//获取ip地址
        /*User user= (User) authentication.getPrincipal();//这里的User是security里面的自己的User
        System.out.println(user.getUsername());
        //password出于安全的考虑,后台打印的值会是null
        System.out.println(user.getPassword());
        System.out.println(user.getAuthorities());*/
        //使用重定向来进行页面跳转访问,内部转发跳转不了
        httpServletResponse.sendRedirect(url);
    }
}

在SecurityConfig里面修改如下代码:
在这里插入图片描述

在谷歌访问http://localhost:8080/login.html,输入用户名admin,密码123,发现跳转过来了
在这里插入图片描述

自定义登录失败处理器

代码和自定义登录成功处理器一样,如下:
在这里插入图片描述
修改SecurityConfig里面的代码:
在这里插入图片描述

基于权限判断

在main.html加入下面一句代码:
在这里插入图片描述
然后在创建一个main1.html文件,如下:
在这里插入图片描述
然后在SecurityConfig里面加上这句代码:
这里的admin权限是以前在UserDetailsServiceImpl类里面写的
在这里插入图片描述
这里的admin权限会去UserDetailsServiceImpl类里面去匹配
在这里插入图片描述
注释掉自定义登录处理器,改成原来的:
在这里插入图片描述

访问登录页面去登录,然后点击main.html的跳转,发现可以正常跳转。

在这里插入图片描述
在这里插入图片描述
匹配多个权限,如下:
在这里插入图片描述

基于角色判断

在UserDetailsServiceImpl添加一个以ROLE_开头的角色
在这里插入图片描述
在这里插入图片描述

基于IP判断

在这里插入图片描述

自定义403错误处理

当出现403错误的时候(也就是权限不够权限),我们不喜欢它自己返回的提示,这时候我们可以自定义一个403处理器。
先在handle文件夹里面新建一个MyAccessDeniedHandler类,如下:
在这里插入图片描述
具体代码如下:

package com.hjl.springsecuritydemo2.handler;

import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

//自定义403权限不足处理逻辑,用于前后端分离
public class MyAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
        //响应状态 403
        httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
        //返回json格式
        httpServletResponse.setHeader("Content-Type","application/json;charset=utf-8");
        PrintWriter printWriter=httpServletResponse.getWriter();
        printWriter.write("{\"status\":\"error\",\"msg\":\"权限不足!\"}");
        printWriter.flush();
        printWriter.close();
    }
}

然后在SecurityConfig里面添加如下代码:
将权限故意写错,测试
在这里插入图片描述
当登录后来到main.html后,点击跳转,出现如下提示:
在这里插入图片描述

使用注解的形式来控制权限

@Secured注解和@PreAuthorize注解

@Secured注解是专门用于判断是否具有角色的。能写在方法或者类上。参数要以ROLE_开头。
@PreAuthorize 既能写基于角色控制也能写基于权限控制 允许角色以ROLE_开头,也允许不以ROLE_开头,都能正确执行,但是SecurityConfig配置类里面是不允许以ROLE_开头的

使用该注解要先去启动类里面添加@EnableGlobalMethodSecurity这个注解

/**
 * @EnableGlobalMethodSecurity 开启springsecurity注解,默认都是关闭的,不加这个security注解就用不了 注解和SecurityConfig里面基于权限控制和基于角色不能同时用,最好写一个
 * securedEnabled = true 开启基于角色的注解 也就是这个LoginController里面的@Secured("ROLE_abc")注解
 * prePostEnabled = true 开启基于权限的注解 也就是这个LoginController里面的@PreAuthorize("hasAuthority('admin')")注解
 */
@SpringBootApplication
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class SpringsecurityDemo2Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringsecurityDemo2Application.class, args);
    }

}

开启注解后,SecurityConfig里面关于权限的都注释掉,否则会出现问题:
在这里插入图片描述
LonginController代码:

package com.hjl.springsecuritydemo2.controller;

import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class LoginController {
    /**
     * 登录方法
     * @Secured 是专门用于判断是否具有角色的。能写在方法或者类上。参数要以ROLE_开头 相当于SecurityConfig配置类里面的hasRole()
     * @PreAuthorize 既能写基于角色控制也能写基于权限控制 允许角色以ROLE_开头,也允许不以ROLE_开头,都能正确执行,但是SecurityConfig配置类里面是不允许以ROLE_开头的
     */
    //@Secured("ROLE_abc")
    //@PreAuthorize("hasRole('abc')")
    @PreAuthorize("hasAuthority('admin')")
    @RequestMapping(value = "/toMain",method = RequestMethod.POST)
    public String toMain(){
        return "redirect:main.html";
    }

    /**
     * 登录失败
     */
    @RequestMapping(value = "/toError",method = RequestMethod.POST)
    public String toError(){
        return "redirect:error.html";
    }
}

thymeleaf中springsecurity的用法

在pom.xml中加入依赖,加入依赖后如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.hjl</groupId>
    <artifactId>springsecurity-demo2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springsecurity-demo2</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--Spring Security组件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!--Web组件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--thymeleaf springsecurity5依赖-->
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
        </dependency>
        <!--thymeleaf依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--test组件 如果需要用Junit来测试,需要下面组件-->
        <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>
    </dependencies>

    <build>
        <!--项目打包需要的组件-->
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

然后在templates里面新建一个demo.html
在这里插入图片描述
demo.html页面代码如下:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
登录账号:<span sec:authentication="name"></span><br/>
登录账号:<span sec:authentication="principal.username"></span><br/>
凭证:<span sec:authentication="credentials"></span><br/>
权限和角色:<span sec:authentication="authorities"></span><br/>
客户端地址:<span sec:authentication="details.remoteAddress"></span><br/>
sessionId:<span sec:authentication="details.sessionId"></span><br/>



通过权限判断:
<button sec:authorize="hasAuthority('/insert')">新增</button>
<button sec:authorize="hasAuthority('/delete')">删除</button>
<button sec:authorize="hasAuthority('/update')">修改</button>
<button sec:authorize="hasAuthority('/select')">查看</button>
<br/>
通过角色判断:
<button sec:authorize="hasRole('abc')">新增</button>
<button sec:authorize="hasRole('abc')">删除</button>
<button sec:authorize="hasRole('abc')">修改</button>
<button sec:authorize="hasRole('abc')">查看</button>
</body>
</html>

然后在LoginController里面添加/demo接口,代码如下:

//如果有用thymeleaf 这么写就是跳转到templates文件下面的demo.html
    @RequestMapping(value = "/demo",method = RequestMethod.GET)
    public String demo(){
        return "demo";
    }

最后在UserDetailsServiceImpl里面的权限集加权限
在这里插入图片描述
然后启动项目,访问http://localhost:8080/login.html进行登录,登录成功后,在访问http://localhost:8080/demo接口,结果如下:
因为没有修改和查看权限,所以按钮不显示
在这里插入图片描述

退出登录

在main.html页面加入如下代码,/logou接口方法是spring security自带的,我们不用写。
在这里插入图片描述
然后在SecurityConfig加入下面的代码:
在这里插入图片描述
然后重启项目,点击main.html页面里的退出登录按钮即可退出登录。退出登录后你发现直接访问main.html是不可能成功的。
在这里插入图片描述
好了,我的学习分享到这里就结束了。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值