springBoot集成springSecurity

springSecurity属于spring的一个安全工具,为我们的应用程序做权限控制,spring cloud security就是基于springSecurity的一套安全工具包。下面我们就来讲解一下springBoot应该如何集成springSecurity。

假设此时你已经配置好了一个springBoot项目,请参考:https://blog.csdn.net/qq_35689573/article/details/80808726,并可以正常启动了,那只需要在pom.xml文件中加入

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

maven项目,写完别忘了右键项目,maven,reimport一下,我们在lib中看到security存在之后才是真正的导入了。

下面启动项目,观察启动日志:

07b25e71-7a9a-42c7-ba6b-845150947dc2是登录密码,此时我们随意访问该项目的任一路径会发现spring不允许,让我们先去进行权限验证:

User可以用springSecurity的默认用户user,Password要用我们上面的随机密码07b25e71-7a9a-42c7-ba6b-845150947dc2,登录成功。我们也可以通过在application.properties或application.yml中进行配置:

spring.security.user.name=hxj
spring.security.user.password=hxj123

至此简单的集成springSecurity我们已经完成了,但是实际项目中肯定不能这么敷衍,那我们会怎么做呢?

首先我们需要知道两个接口:UserDetailsService和WebSecurityConfigurerAdapter,UserDetailsService里面只有一个方法:

public interface UserDetailsService {
    UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}

顾名思义就是通过用户名加载用户并返回一个UserDetails对象,

public interface UserDetails extends Serializable {
    Collection<? extends GrantedAuthority> getAuthorities();

    String getPassword();

    String getUsername();

    boolean isAccountNonExpired();

    boolean isAccountNonLocked();

    boolean isCredentialsNonExpired();

    boolean isEnabled();
}

UserDetails里面封装了用户的一些基本信息,如用户名,用户密码,用户权限集合之类的。

WebSecurityConfigurerAdapter这是一个抽象类,权限配置适配器,所有用户登录时做的权限处理应该都在这里面。

下面我们先来实现UserDetailsService:

import com.example.springBootDemo.config.datasource.DaoHelper;
import com.example.springBootDemo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
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;

@Component
public class MyUserDetailsService implements UserDetailsService {
    @Autowired
    private DaoHelper daoHelper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = (User)daoHelper.queryOne("user.getUserByName",username);
        return new org.springframework.security.core.userdetails.User(username,user.getPassword(),AuthorityUtils.commaSeparatedStringToAuthorityList(user.getRole()));
    }
}

我们通过username从数据库中查询出对应的用户并把它强转成我们自定义的User对象,从这个User对象中提取信息,最终返回一个UserDetails对象。

再来看WebSecurityConfigurerAdapter:

@Configuration
public class MyWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

    /**
     * 将我们在后台查询出来的用户信息配置成bean交给springSecurity的权限适配器
     * */
    @Bean
    public UserDetailsService userDetailsService(){
        return new MyUserDetailsService();
    }

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

    /**
     * 对请求路径中带css,img,js的请求内容不进行权限拦截
     * 根据实际情况合理增删
     * */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/css/**","/img/**","/js/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.headers().and().authorizeRequests()
                .anyRequest().authenticated()
                //登录路径,对应LoginController中的signIn方法,我们可以在这个方法中添加我们在进入登录页面前的一些逻辑
                .and().formLogin().loginPage("/signIn")
                //跳转到login页面,登录成功后默认跳转到index
                .loginProcessingUrl("/login").defaultSuccessUrl("/index",true)
                //登录失败跳转页面
                .failureUrl("/signIn?error").permitAll()
                //失效session跳转路径
                .and().sessionManagement().invalidSessionUrl("/signIn")
                //session失效时间
                .and().rememberMe().tokenValiditySeconds(1209600)
                //掉线之后的跳转路径
                .and().logout().logoutSuccessUrl("/signIn").permitAll()
                .and().csrf().disable();
    }

}

MyWebSecurityConfigurerAdapter中主要重写了WebSecurityConfigurerAdapter中的三个方法,定义了登录方法和登录页面的一下权限控制。

LoginController:

@Controller
public class LoginController {

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

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

login.html页面(我用的是thymleaf模板引擎):

图中圈中的地方注意一下,“/login”是在MyWebSecurityConfigurerAdapter中定义好的,其他都是springSecurity默认的。

访问:http://localhost:8080/index,会发现直接被拦截跳转到了http://localhost:8080/signIn

点击登录,观察后台日志:

是因为我们一般存在数据库中的密码是加密的,但是我们在这里没有设置解密方式,所以我们还需要在MyWebSecurityConfigurerAdapter添加如下代码

   /**
     * 定义解码器
     * */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

并将定义的密码器注入到

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

此时我们再次访问http://localhost:8080/signIn,输入账号密码之后成功登入系统。

我们也可以自己定义加密规则:

@Component
public class MypasswordEncoder implements PasswordEncoder {

    @Override
    public String encode(CharSequence charSequence) {
        //定义加密规则并返回加密后的密码
        return charSequence.toString();//此处我们就不加密了,直接返回明文
    }

    @Override
    public boolean matches(CharSequence charSequence, String s) {
        return charSequence.equals(s);//上面没有加密,此处也就不用解密了
    }
}

并注入MyWebSecurityConfigurerAdapter中:

   /**
     * 定义解码器
     * */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new MypasswordEncoder();
    }

此时我们将数据库中的密码换成明文,登录成功。至此springSecurity的简单应用完成,其他配置请参考官方文档:

http://www.mossle.com/docs/springsecurity3/html/springsecurity.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值