springsecurity 认证,授权,注销,动态菜单,记住我和首页定制

发布时间 2023-05-07 14:19:01作者: 醒醒起来

搭建环境:

1.在创建springboot时选择组件web,thymeleaf,spring-security

2.导入静态资源,导入后测试一下环境

 认证和授权

继承类WebSecurityConfigurerAdapter,重写方法configure

若遇到报错:

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
at org.springframework.security.crypto.password.DelegatingPasswordEncoder$UnmappedIdPasswordEncoder.matches(DelegatingPasswordEncoder.java:289) ~[spring-security-crypto-5.7.8.jar:5.7.8]
at org.springframework.security.crypto.password.DelegatingPasswordEncoder.matches(DelegatingPasswordEncoder.java:237) ~[spring-security-crypto-5.7.8.jar:5.7.8]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$LazyPasswordEncoder.matches(WebSecurityConfigurerAdapter.java:616) ~[spring-security-config-5.7.8.jar:5.7.8]
at org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks(DaoAuthenticationProvider.java:77) ~[spring-security-core-5.7.8.jar:5.7.8]
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:147) ~[spring-security-core-5.7.8.jar:5.7.8]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182) ~[spring-security-core-5.7.8.jar:5.7.8]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:201) ~[spring-security-core-5.7.8.jar:5.7.8]
at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(

是因为设置的密码没有加密啊,springsecurity5.0+要求对密码加密,因为不加密很容易被反编译,造成信息泄露

代码:

@EnableWebSecurity
public class SecurityConfig  extends WebSecurityConfigurerAdapter {
    protected void configure(HttpSecurity http) throws Exception {
        //首页all可以访问,功能页对应vip能访问
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");
        //没有权限默认跳到登录页面,默认开启登录的页面
        http.formLogin();

    }
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
       auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
               .withUser("kuangshen").password(new BCryptPasswordEncoder().encode("123")).roles("vip2","vip3")
               .and()
               .withUser("ROOT").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
               .and()
               .withUser("GUEST").password(new BCryptPasswordEncoder().encode("12")).roles("vip3");
    }
}

 

 

注销

要求实现:未登录:只显示登录按钮,登录时 显示登陆角色和注销按钮

前端代码要做的事情是验证,需要导入整合thymeleaf和springsecurity的依赖

<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>

前端代码:

前端判断:如果用户未登录(!isAuthenticated()),那要跳到登录页面,如果用户是登录的,定制首页要展示出用户的角色(vip1?vip2?vip3?),和注销图标

 运行结果:

 

动态菜单

动态菜单:不同角色登录看到的内容不同

前端代码:

只需要在每个功能模块前面添加判断是什么角色

运行结果:

可以看到用户kuangshen角色是vip2和vip3,因此可以看到对应的两个功能模块Level2和Level3

 记住我

记住我的本质是在用户访问时增加cookie

在前端添加:

 

在secruityconfig开启:

 

首页定制

我们不想继续使用springsecurity5提供的登录页面了,因此我们自定义了一个login.html,我们希望之后按登录按钮时跳转到自己定制的登录页面

在RouterController中,"views/login"对应的是/toLogin,在index.html页面请求的/toLogin经过这条语句会跳转到“views/login",在login.html面请求的/toLogin经过这条语句表单提交到index.html; 因此这里的/toLogin和index.html的/toLogin和login。html的/toLogin要完全一致,不然会报404

 login.html

 index.html