springboot整合springSecurity入门案例(实现登录,记住我等常用标签使用)

一,整合进依赖

每个依赖都标了注释,大家可以按照自己需要的来添加,置于配置问件啥的,大家可以参考springboot+mybatisplus+redis整合(附上脚手架完整代码)

  <!--主要就是加了这个依赖-->
  <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
        <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>
        <!--fastjson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
        <!--web 启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--模板引擎thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--mysql连接-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.11</version>
        </dependency>
        <!--druid数据源-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.8</version>
        </dependency>
        <!--mybatis-plus以及生成器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.2.0</version>
        </dependency>

        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.29</version>
        </dependency>
        <!--单元测试-->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
        <!--lombok用来简化实体类-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
       <!-- 单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>

二,配置过滤规则(类似配置shiro中的ShiroFilterFactoryBean)

大致内容:配置一些登录的跳转,及权限、登录验证的跳转规则。和记住我实现自动登录的配置。

/**
 * @author 张子行
 * @class WebSecurityConfigurerAdapter
 */
@Configuration
public class SecurityConfigTest extends WebSecurityConfigurerAdapter {
    
    
    @Autowired
    private UserDetailsService userDetailsService;
    //注入数据源
    @Autowired
    private DataSource dataSource;

    /**
     * @param
     * @method 配置登录记住我,记住我相关的底层数据库的相关配置,生成的token存储在里面
     */
    @Bean
    public PersistentTokenRepository persistentTokenRepository() {
    
    
        JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
        jdbcTokenRepository.setDataSource(dataSource);
        //开启后token会存储在这张表里面
        //jdbcTokenRepository.setCreateTableOnStartup(true);
        return jdbcTokenRepository;
    }

    /**
     * @param
     * @method 配置授权认证逻辑
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    
    
        auth.userDetailsService(userDetailsService).passwordEncoder(password());
    }

    /**
     * @param
     * @method 密码加密规则
     */
    @Bean
    PasswordEncoder password() {
    
    
        return new BCryptPasswordEncoder();
    }

    /**
     * @param
     * @method 配置过滤规则 url层面
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    
    
        //退出
        http.logout().logoutUrl("/logout").
                logoutSuccessUrl("/test/hello").permitAll();

        //配置没有权限访问跳转自定义页面
        http.exceptionHandling().accessDeniedPage("/unauth.html");
        http.authorizeRequests()
                .antMatchers("/", "/test/hello", "/user/login").permitAll() //设置哪些路径可以直接访问,不需要认证
                //当前登录用户,只有具有admins权限才可以访问这个路径
                //1 hasAuthority方法
                // .antMatchers("/test/index").hasAuthority("admins")
                //2 hasAnyAuthority方法
                // .antMatchers("/test/index").hasAnyAuthority("admins,manager")
                //3 hasRole方法   ROLE_sale
                .antMatchers("/test/index").hasRole("sale")
                .anyRequest().authenticated();
        //配置 登录的相关
        http.formLogin()   //自定义自己编写的登录页面
                .loginPage("/on.html")  //登录页面设置
                .loginProcessingUrl("/user/login")   //登录访问路径
                .defaultSuccessUrl("/success.html").permitAll()  //登录成功之后,跳转路径
                .failureUrl("/unauth.html");

        //配置 自动登录记住我
        http.rememberMe()
                .tokenRepository(persistentTokenRepository())
                .tokenValiditySeconds(60).userDetailsService(userDetailsService);

        //关闭csrf防护
        http.csrf().disable();
    }
}

三,编写登录认证逻辑

大体逻辑:根据用户名查询用户信息,及其权限返回

/**
 * @author 张子行
 * @class UserDetailsService
 */
@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
    
    

    @Autowired
    private UsersMapper usersMapper;

    /**
     * @param
     * @method 登录逻辑
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    
    
        //调用usersMapper方法,根据用户名查询数据库
        QueryWrapper<User> wrapper = new QueryWrapper();
        // where username=?
        wrapper.eq("username", username);
        User user = usersMapper.selectOne(wrapper);

        //判断
        if (user == null) {
    
    //数据库没有用户名,认证失败
            throw new UsernameNotFoundException("用户名不存在!");
        }

        //角色要加前缀ROLE_ ,权限直接没啥要求
        List<GrantedAuthority> auths =
                AuthorityUtils.commaSeparatedStringToAuthorityList("admins,ROLE_sale");
        //从查询数据库返回users对象,得到用户名和密码,返回
        return new org.springframework.security.core.userdetails.User(user.getUsername(),
                new BCryptPasswordEncoder().encode(user.getPassword()), auths);
    }
}

四,编写html页面

主要写下登录页面,注意这里的action="/user/login"就是我们配置过的登录的请求action

<h1>static表单提交11</h1>
<!-- 表单提交用户信息,注意字段的设置,直接是*{} -->
<form action="/user/login" method="post">
    <input type="text" name="username"/>
    <input type="text" name="password"/>
    <input type="checkbox" name="remember-me"/>自动登录
    <input type="submit"/>
</form>

五,编写controller

大体对以下的注解做了个测试

注解 作用 可选参数
@PreAuthorize 在入方法之前拦截 hasPermission(),hasRole(),hasAnyAuthority(),hasAnyRole(),hasAuthority()
@PostAuthorize 在出方法之前拦截 ,如果没有相关权限,虽执行方法但是还是没有通过认证,返回页面显示没有权限 hasPermission(),hasRole(),hasAnyAuthority(),hasAnyRole(),hasAuthority()
@PostFilter 只返回指定的model信息 filterObject.username == ‘zzh’
/**
 * @author 张子行
 * @class TestController
 */
@RestController
@RequestMapping("/test")
public class TestController {
    
    

    @GetMapping("hello")
    public String hello() {
    
    
        return "hello security";
    }

    @GetMapping("index")
    public String index() {
    
    
        return "hello index";
    }

    @GetMapping("update")
    //@Secured({"ROLE_sale","ROLE_manager"})
    @PreAuthorize("hasAnyAuthority('admins')")
    @PostAuthorize("hasAnyAuthority('admins1')")
    public String update() {
    
    
        System.out.println("update......");
        return "hello update";
    }

    @GetMapping("getAll")
    @PostAuthorize("hasAnyAuthority('admins')")
    @PostFilter("filterObject.username == 'admin1'")
    public List<User> getAllUser(){
    
    
        ArrayList<User> list = new ArrayList<>();
        User user = new User();
        user.setId(1);
        user.setPassword("666");
        user.setUsername("zzh");
        list.add(user);
        return list;
    }


}

六,测试

1:输入任何url都要求登录
在这里插入图片描述

2:点登录提交,登录名密码错误或者为空都登不进
在这里插入图片描述

3:登录成功,可以正常访问那些页面喽,关闭浏览器,重新进入那些需要权限的页面,无需再次登录即可进去,记住我功能成功
在这里插入图片描述
在这里插入图片描述
4:自动生成的token表有数据
在这里插入图片描述

本文测试源码

觉着不错的点个小星星吧,爱你哟!

猜你喜欢

转载自blog.csdn.net/qq_42875345/article/details/110120032