springboot之集成Security(入门)

springboot之集成Security,实现认证授权,权限控制

  • 搭建框架
    使用security之前,需要先搭建一个web框架。
    比如我的是这样的

    然后写一个路由转接器。
@Controller
public class RouterController {

    @RequestMapping({"/","/index"})
    public String index() {
        return "index";
    }

    @RequestMapping("/toLogin")
    public String toLogin() {
        return "views/login";
    }

    @RequestMapping("/level1/{id}")
    public String level1(@PathVariable("id") int id) {
        return "views/level1/" + id;
    }

    @RequestMapping("/level2/{id}")
    public String level2(@PathVariable("id") int id) {
        return "views/level2/" + id;
    }

    @RequestMapping("/level3/{id}")
    public String level3(@PathVariable("id") int id) {
        return "views/level3/" + id;
    }

}

然后就可以开始重点的部分了。

  • 导包,需要一个security的包,和一个thymeleaf整合包,后面权限控制用
<!--thymeleaf整合包-->
<dependency>
	<groupId>org.thymeleaf.extras</groupId>
	<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<!--boot-starter-security-->
     <dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>
  • 用户认证和授权
    我们需要有有一个配置类,继承WebSecurityConfigurerAdapter,然后重写里面的方法。我的习惯,Talking is cheap~~ 还是先上代码吧
//认证
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/").permitAll()//任何人都可以访问
                .antMatchers("/index").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")//需要vip?权限,下同
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");

          http.formLogin();//开启登录页面
    }
    
}
 认证步骤:
1. 继承 WebSecurityConfigurerAdapter 类
2. 重写 configure(HttpSecurity http) 方法,
3. 方法里面写你需要的配置
4. 开启注释 @EnableWebSecurity,托管给springboot。

一旦给页面写了权限认证,在新版的security框架中,进入需要权限的页面,会自动判断跳转一个登录页面,自带的。然后要求你登录。

 //授权
 @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("fang").password(new BCryptPasswordEncoder().encode("123123")).roles("vip1", "vip2", "vip3")
                .and()
                .withUser("root").password(new BCryptPasswordEncoder().encode("123123")).roles("vip1", "vip2")
                .and()
                .withUser("guest").password(new BCryptPasswordEncoder().encode("123123")).roles("vip1");

    }
授权步骤:
1. 重写 configure(AuthenticationManagerBuilder auth) 方法
2. 方法里面写你需要的配置

说明一下
方法中的auth.inMemoryAuthentication()表示在内存中认证,.passwordEncoder(new BCryptPasswordEncoder())是密码加密。roles()授权

如果需要用数据库认证,看下面官网的例子

@Autowired
private DataSource dataSource;

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
	auth
		.jdbcAuthentication()
			.dataSource(dataSource)
			.withDefaultSchema()
			.withUser("user").password("password").roles("USER")
			.and()
			.withUser("admin").password("password").roles("USER", "ADMIN");
}

这样一来,用户的授权和认证都可以啦。运行测试一下。

或者用我们自己写的方法

    @Autowired
    private UserDetailsService userDetailsService;//自己写的

    // 授权
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }
    
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
import com.fang.blogsystem.mapper.UserMapper;
import com.fang.blogsystem.pojo.DO.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
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;

/**
 * @author Bernie_xin
 * @create 2020/12/4 16:16
 **/
@Service("userDetailsService")//注意一定要加
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private UserMapper loginUserMapper;

    //在这里返回用户名和密码以及权限
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        //根据用户名做查询
        User user = loginUserMapper.findUser(s);
        if (user == null){
            throw new UsernameNotFoundException("用户名不存在");
        }

        List<GrantedAuthority> auth = AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_admin");//这里本来也应该是数据库连表查询的
        return new org.springframework.security.core.userdetails.User(user.getUsername(),//这里返回的user一定要是springframework.security的,由于我上面自己的user重名了,只能这么写。建议自己的用户类不需要写user,用sys_user之类的
                new BCryptPasswordEncoder().encode(user.getPassword()),
                auth);
    }

}

没问题则继续

  • 登录页面,退出登录以及首页配置

我们上面用的是security自带的首页页面,但是我想用我自己的页面。怎么设置呢?
很简单,在 http.formLogin() 后面继续 .loginPage("/toLogin")。toLogin是我们前面写的去登录页面的请求。

我们在登录之后,首页就不应该再有什么登录的按钮啦,应该是注销按钮。

			<!--登录注销-->
            <div class="right menu">
                <!--未登录-->
                <div sec:authorize="!isAuthenticated()">
                    <a  th:href="@{/toLogin}">
                        登录
                    </a>
                </div>
                <!--注销-->
                <div sec:authorize="isAuthenticated()">
                    <a th:href="@{/toLogin}">
                         注销
                    </a>
                </div>

通过sec:authorize="!isAuthenticated()判断是否登录。使用这个之前,需要导入命名空间。不导入也可以使用,但是会飘红报错。
导入方法:
页面顶部的html标签里面加上

<html lang="en" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">

然后要开启注销。一行代码搞定

http.logout().logoutSuccessUrl("/");//logoutSuccessUrl("退出成功后跳转的页面")

最后就是把那些没有访问权限的页面隐藏。
也不难。就是在链接外面写一个div,里面sec:authorize="hasRole('权限')",看下面的例子

<div sec:authorize="hasRole('vip1')">
	<a th:href="@{/level1/1}">Level-1-1</a>
</div>

然后测试,发现没有vip1,我都看不到Level-1-1。完成!

security学习的简单记录。如果这个篇博客对你有帮助。麻烦点个赞!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值