Security学习

1.jar包

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

2 .application里面改密码

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

3 . config(基础版 在内存中)

package com.aaa.config;
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.User;
import org.springframework.security.core.userdetails.UserDetails;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * AuthenticationManagerBuilder  认证管理器的构建者
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //UserDeatils
        UserDetails user = User.withDefaultPasswordEncoder()  //默认不支持明文密码  -> 加密  使用默认的加密方式
                .username("test")  //用户名
                .password("123456")  //密码
                .roles("USER")
                .build();  //构建
        auth.inMemoryAuthentication()  //将用户信息存放到内存里面
                .withUser(user); //存放的 user
    }
}
//另一种方式
 @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 创建密码解析器
        BCryptPasswordEncoder pe =new BCryptPasswordEncoder();
        // 对密码进行加密
        String password = pe.encode("123456");
        auth.inMemoryAuthentication()
                .passwordEncoder(pe)  //默认没有,需要手动设置BCryptPasswordEncoder  加密 ->对比(并非解密,仅对比加密结果)
                .withUser("test")
                .password(password)
                .roles("USER")
        ;
    }

4 . 自定义登录页面

static包下写login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/userlogin" method="post">
    用户名:<input type="text" name="username">
    <br/>
    用户名:<input type="password" name="password">
    <br/>
    <input type="submit" value="login">
</form>
</body>
</html>

config里面配置放行

@Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置 登录form表单
        //路径的前面,必须加 /
        http.formLogin()
                .loginPage("/login.html")
                .loginProcessingUrl("/userlogin"); //提交路径
        http.authorizeRequests().antMatchers("/login.html","/userlogin","/").permitAll();//代表放行"/login.html","/userlogin","/"
        //其他都需要拦截
        http.authorizeRequests().anyRequest().authenticated();
        // csrf 方便HTML文件通过
        http.csrf().disable();
    }

提交以下三点都应相同

配置参数的名字

Login.html中 为什么用户名的name要写成username

如果不想使用原来的username参数

Html中:

http://localhost:8080/test

访问的路径/test

认证成功之后跳转到的路径就是test

从login.html进行登录的时候 登录成功才会跳转到/success路径里面

配置一个角色放行

配置一个放行拦截
 http.authorizeRequests().antMatchers("/test").hasRole("USER");
配置一个角色
 auth.inMemoryAuthentication()
                .passwordEncoder(pe)  //默认没有,需要手动设置BCryptPasswordEncoder  加密 ->对比(并非解密,仅对比加密结果)
                .withUser("test2")
                .password(password)
                .roles("ADMIN")
        ;

显示无权限

配置一个资源放行

此时test2可以通行,test显示权限不足403

//        http.authorizeRequests().antMatchers("/test").hasRole("USER");
        //现在test2 有testpath资源 ,test没有
        http.authorizeRequests().antMatchers("/test").hasAuthority("testpath");

 //(List<? extends GrantedAuthority> authorities) {
        //            this.user.authorities(authorities);

        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority("testpath"));
        auth.inMemoryAuthentication()
                .passwordEncoder(pe)  //默认没有,需要手动设置BCryptPasswordEncoder  加密 ->对比(并非解密,仅对比加密结果)
                .withUser("test2")
                .password(password)
                .roles("ADMIN")
                .authorities(authorities)//所有的资源的信息 包含角色 ,菜单
        ;

配置资源信息的时候角色一定是以ROLE_为开始的

3.8 注解的使用

使用注解前需要在启动器或配置类上添加注解:

@EnableGlobalMethodSecurity(securedEnabled=true,prePostEnabled = true,jsr250Enabled=true)

@Secured:判断是否具有角色:

@Secured({"ROLE_admin"})
@RequestMapping("testSecured")
public String testSecured() {
    return "testSecured";
}

注意:使用这个这个注解的时候对应的角色信息必须是以ROLE_**的形式出现,否则无法识别

运行结果:

@RolesAllowed:判断是否具有角色:

@RolesAllowed({"ADMIN"})
@RequestMapping("testSecured")
public String testSecured() {
    return "testSecured";
}

注意:此注解不需要特别添加前缀ROLE_

@PreAuthorize:进入方法前进行权限验证, @PreAuthorize 可以将登录用户的 权限参数传到方法中。

    @RequestMapping("/preAuthorize")
//@PreAuthorize("hasRole('ROLE_ADMIN')")
    @PreAuthorize("hasAnyAuthority('findAll')")
    public String preAuthorize(){
        System.out.println("preAuthorize");
        return "preAuthorize";
    }

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

获取用户的认证的信息(三种方式)

@RestController
public class UserController {
    @GetMapping("user1")
    public Object getUser(Principal principal){
        return principal;
    }

    @GetMapping("user2")
    public Object getUser2(Authentication authentication){
        return authentication;
    }

    @GetMapping("user3")
    public Object getUser3(){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return authentication;
    }
}

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值