springSecurity

发布于:2023-01-14 ⋅ 阅读:(402) ⋅ 点赞:(0)

目录

入门案例

修改默认的账号密码

mybaits-plus整合security

springSecurityConfig类configure方法

securityConfig配置


入门案例

springSecurity安全主要用于登录

1.导入所需的依赖

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

2.编写一个controller

package com.hang.demo2.controller;
​
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
​
@RestController
@RequestMapping("/Test")
public class TestController {
    @GetMapping("add")
    public String add(){
        return "hello security";
    }
}

运行后就会出现登录页面

账号默认是:user

密码会打印在控制台

修改默认的账号密码

修改默认账号后密码不会打印在控制台了

通过配置文件修改

spring.security.user.name=hang
spring.security.user.password=123456

编写类实现接口

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        //      给密码加密
        String password = passwordEncoder.encode("123");
        auth.inMemoryAuthentication().withUser("hang").password(password).roles("admin");
    }
    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

.inMemoryAuthentication: 给这个账号存到内存当中去

.withUser("hang"):设置用户名

.password(password):设置密码

.roles("admin"):设置角色

自定义编写实现类

package com.hang.demo2.config;
​
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
​
@Configuration
public class SecurityConfigTest extends WebSecurityConfigurerAdapter {
​
    @Autowired
    private UserDetailsService userDetailsService;
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
        auth.userDetailsService(userDetailsService).passwordEncoder(password());
    }
​
    @Bean
    PasswordEncoder password(){
        return new BCryptPasswordEncoder();
    }
}

继承WebSecurityConfigurerAdapter类 并且实现其方法configure

package com.hang.demo2.service;
​
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.GrantedAuthority;
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.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
​
import java.util.List;
​
@Service(value = "userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("role");
        return new User("hang",new BCryptPasswordEncoder().encode("123"),auths);
    }
}

这里service的值一定要和SecurityConfigTest类里面的UserDetailsService 变量名一致 要不然会注入不进去

auths不能为空 可以随便写一个

mybaits-plus整合security

1.导入所需的依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 连接数据库依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- mybatis-plus依赖 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>
        <!-- Lombok依赖 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!-- security依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
​
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

2.编写连接数据库配置文件

#spring.security.user.name=hang
#spring.security.user.password=123456
​
spring.datasource.url=jdbc:mysql://localhost:3306/sys?serverTimezone=GMT
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
​
mybatis-plus.global-config.banner=false

3.编写实体类

package com.hang.demo2.pojo;
​
import lombok.Data;
​
@Data
public class Users {
  private long id;
  private String username;
  private String password;
}

4.编写security工具类

package com.hang.demo2.config;
​
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
​
@Configuration
public class SecurityConfigTest extends WebSecurityConfigurerAdapter {
​
    @Autowired
    private UserDetailsService userDetailsService;
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
        auth.userDetailsService(userDetailsService).passwordEncoder(password());
    }
​
    @Bean
    PasswordEncoder password(){
        return new BCryptPasswordEncoder();
    }
}

4.编写连接数据库的类

package com.hang.demo2.mapper;
​
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import com.hang.demo2.pojo.*;
@Mapper
@Repository
public interface UserMapper extends BaseMapper<Users> {
}

5.编写mapper类

package com.hang.demo2.mapper;
​
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import com.hang.demo2.pojo.*;
@Mapper
@Repository
public interface UserMapper extends BaseMapper<Users> {
}

因为运用到了mybatis-plus 所以说只需要继承BaseMapper这个类就行了

6.编写service类

package com.hang.demo2.service;
​
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hang.demo2.mapper.UserMapper;
import com.hang.demo2.pojo.Users;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.GrantedAuthority;
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.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
​
import java.util.List;
​
@Service(value = "userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
        //给一个查询的条件
        queryWrapper.eq("username",username);
        //selectOne查询一条数据
        Users users = userMapper.selectOne(queryWrapper);
        System.out.println("users = " + users);
        if (users==null) {
             throw new UsernameNotFoundException("出错了");
        }
        List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("role");
        return new User(username,new BCryptPasswordEncoder().encode(users.getPassword()),auths);
    }
}

这里@Service的value一定要和security工具类UserDetailsService值一致

springSecurityConfig类configure方法

修改默认登录页面

在工具类里面(继承WebSecurityConfigurerAdapter的那个)

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.exceptionHandling().accessDeniedPage("/unAuth.html");
        http.formLogin()        //自定义编写的登录页面
                .loginPage("/login.html")   //登录页面的设置
                .loginProcessingUrl("/user/login")    //登录访问路径
                .defaultSuccessUrl("/Test/index").permitAll()    //登录成功后跳转的页面
                .and().authorizeRequests()
                .antMatchers("/","/Test/add","/user/login").permitAll() //不需要登录也能访问的页面
//                .antMatchers().hasAuthority("admin")      //访问什么页面需要什么权限 hasAuthority 必须有这个
                .antMatchers("/Test/hang").hasAnyAuthority("admin,hang")    //访问这个页面需要什么权限 有其中一个即可
                .anyRequest().authenticated()
                .and().csrf().disable();    //关闭csrf保护
    }

设置权限

在工具类里面 config(HttpSecurity http)方法里面

//访问什么页面需要什么权限 hasAuthority 必须有这个
.antMatchers().hasAuthority("admin")  
.antMatchers("/Test/hang").hasAnyAuthority("admin,hang")

这段代码的意思是 进入/Test/Hang需要有admin或者是hang其中一个权限

在service类里面 以下代码就是给权限

List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("hang");
return new User(username,new BCryptPasswordEncoder().encode(users.getPassword()),auths);

意思是给了一个hang的权限

:如果访问没有权限的页面会显示403、

修改403页面

所以说我们可以优化页面 修改403时候显示的页面

http.exceptionHandling().accessDeniedPage("/unAuth.html");

使用注解实现给方法设置权限

@Secured({"zhang"})
@ResponseBody
@GetMapping("zhang")
public String zhang(){
    return "hello zhang";
}

@Secured({"zhang"}) :意思是需要有张这个权限才能进入此方法

使用之前 需要在启动方法上加注解

@EnableGlobalMethodSecurity(securedEnabled = true)

意思是开启springsecurity注解扫描

退出

http.logout().logoutUrl("/logout")
        .logoutSuccessUrl("/security.html").permitAll();

:在点击退出的时候 跳转的路径也要是/logout,下面这个路径是退出后跳转的页面

securityConfig配置

package com.hang.demo2.config;
​
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
​
@Configuration
public class SecurityConfigTest extends WebSecurityConfigurerAdapter {
​
    @Autowired
    private UserDetailsService userDetailsService;
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
        auth.userDetailsService(userDetailsService).passwordEncoder(password());
    }
​
    @Bean
    PasswordEncoder password(){
        return new BCryptPasswordEncoder();
    }
​
    @Override
        protected void configure(HttpSecurity http) throws Exception {
//      退出的logout
        http.logout().logoutUrl("/logout")
//                退出后去到哪个页面
                .logoutSuccessUrl("/security.html").permitAll();
//      如果没有权限时候显示的页面403
        http.exceptionHandling().accessDeniedPage("/unAuth.html");
        http.formLogin()        //自定义编写的登录页面
                .loginPage("/login.html")   //登录页面的设置
                .loginProcessingUrl("/user/login")    //登录访问路径
                .defaultSuccessUrl("/Test/index").permitAll()    //登录成功后跳转的页面
                .and().authorizeRequests()
                .antMatchers("/","/Test/add","/user/login").permitAll() //不需要登录也能访问的页面
//                .antMatchers().hasAuthority("admin")      //访问什么页面需要什么权限 hasAuthority 必须有这个
                .antMatchers("/Test/hang").hasAnyAuthority("admin,hang")    //访问这个页面需要什么权限 有其中一个即可
                .anyRequest().authenticated()
                .and().csrf().disable();    //关闭csrf保护
    }
}