Spring Security笔记

需求

  • 导入依赖
  • 配置
  • 应用

导入依赖

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

作用:

  • 所有的http请求都需要认证
  • 对不同的请求路径,执行不同的安全规则
  • 通过登录页面来提示用户进行认证
  • 认证过程是通过HTTP basic认证对话框实现的
  • 提供多个用户,并且设置权限

配置spring security

基于内存的配置

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("lei")
                    .password("123456")
                    .authorities("ROLE_USER")
             .and()
                .withUser("liu")
                .password("1233456")
                .authorities("ROLE_USER");
    }
}

在上面的代码中,通过inMemoryAuthentication()方法创建了两个用户,并且每个用户的权限都是ROLE_USER.

基于JDBC的用户存储

@Configuration
@EnableWebSecurity
public class SecurityConfigs {
    @Resource
    DataSource dataSource;

    protected  void  configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .jdbcAuthentication()
                .dataSource(dataSource)
                .usersByUsernameQuery(
                        "select username,password,enabled from Users" +
                                "where username = ?"
                )
                .authoritiesByUsernameQuery(
                        "select  username,authority from UserAuthorities "+
                                "where username =?"
                )
        .passwordEncoder(new StandardPasswordEncoder("53cr3t"));
    }
}

上述代码,配置了数据库,以及查询用户信息、解码的sql语句。

自定义用户认证

定义用户实体类

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements UserDetails {
     private  static final long serialVersionUID =1L;

     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)
     private Long id;
     private String username;
     private String password;
     private String fullname;
     private String street;
     private String city;
     private String state;
     private String zip;
     private String phoneNumber;


    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

上述代码实现了UserDeatils接口,这样我们能够提供更多信息给框架,比如用户都被授予了哪些权限以及用户的账号是否可用。

创建用户持久层

@Repository
public interface UserDao extends CrudRepository<User,Long> {
    User findByUsername(String username);
}

创建用户服务层

用户服务层·

@Service
public class UserRepositoryUserDetailsService implements UserDetailsService{

    @Autowired
    UserDao userDao;

    @Override
    public UserDetails loadUserByUsername(String username) {
        User user = userDao.findByUsername(username);
        if (user!=null){
            return user;
        }
        throw new UsernameNotFoundException("User"+username+"not found");
    }
}

配置类

@Configuration
@EnableWebSecurity
public class SecurityConfigss extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserRepositoryUserDetailsService userDetailsService;

    @Bean
    public PasswordEncoder encoder(){
        return new StandardPasswordEncoder("53cr3t");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(userDetailsService)
                .passwordEncoder(encoder());
    }
}

保护请求

配置类

@Configuration
@EnableWebSecurity
public class SecurityConfigss extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserRepositoryUserDetailsService userDetailsService;

    @Bean
    public PasswordEncoder encoder(){
        return new StandardPasswordEncoder("53cr3t");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(userDetailsService)
                .passwordEncoder(encoder());
    }

    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests()
                  .antMatchers("/design","/orders")
                    .hasRole("ROLE_USER")
                  .antMatchers("/","/*")
                    .permitAll()
                .and()
                    .formLogin()
                        .loginPage("/login")
                        .defaultSuccessUrl("/design",true)
                .and()
                    .logout()
                        .logoutSuccessUrl("/out")
                .and()
                    .csrf()
                        .disable();

    }
}
  • antMatchers("/design","/orders") 添加url
  • hasRole(“ROLE_USER”) 必须拥有ROLE_USER权限的才可以访问上面添加的url
  • antMatchers("/","/*") 添加所有url
  • .permitAll() 所有用户都可以访问的,但是基于前面的条件(必须拥有ROLE_USER权限的才可以访问("/design","/orders"))
  • formLogin().loginPage("/login") 添加用户登录界面,也就是用户如果没有登录,会自动跳转到这个界面
  • .defaultSuccessUrl("/design",true) 登录成功后,如果添加了true这个参数,则默认添加到这个界面。
  • .logout().logoutSuccessUrl("/out") 退出后默认跳转的页面
  • csrf() .disable(); 禁用csfr,容易造成“跨站请求伪造”。如果不禁用的情况下可以在前端中添加一个隐藏的token。

获取用户信息

@RestController
@RequestMapping("/get")
public class GetUserInfo {

    @ResponseBody
    @PostMapping
    public User getUserInfo(Authentication authentication){
        User user = (User) authentication.getPrincipal();
        return user;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值