根据下面博客来学习:
https://blog.csdn.net/yuanlaijike/article/details/80249235
想达成该博客中的效果,有其他方法。
首先注销掉controller层的 @PreAuthorize("hasRole('ROLE_ADMIN')")
在配置中添加规则
.antMatchers("/admin").hasRole("ADMIN")
.antMatchers("/user").hasRole("USER")
笔记:
1、SpringSecurity依赖引入后,浏览器进入端口号地址,security会给一个默认的登录表单(拦截所有请求)。通过验证后才能正常使用项目功能。
当希望使用自定义登录表单,需要写配置类
@Configuration
/**@EnableWebSecurity注解有两个作用
* 1: 加载了WebSecurityConfiguration配置类, 配置安全认证策略。
* 2: 加载了AuthenticationConfiguration, 配置了认证信息
*/
@EnableWebSecurity
//该配置类继承SpringSecurity的WebSecurityConfigurerAdapter
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
//重写http请求的configure方法
@Override
protected void configure(HttpSecurity http) throws Exception {
//跳转到controller中的/login路径方法
http
//表示表单认证的方式
.formLogin()
.loginPage("/login");
}
}
此时,返回的是我们自己编写的登录页面
2、configure中其他配置
共有三个configure
configure(WebSecurity) 通过重载,配置Spring Security的Filter链。
configure(HttpSecurity) 通过重载,配置如何通过拦截器保护请求。
configure(AuthenticationManagerBuiler) 通过重载配置user-detail 服务。
(1)configure(HttpSecurity)
protected void configure(HttpSecurity http ) throws Exception {
http
.authorizeRequests() 1
.antMatchers( "/resources/**", "/signup" , "/about").permitAll() 2
.antMatchers( "/admin/**").hasRole("ADMIN") 3
.antMatchers( "/db/**").access("hasRole('ADMIN') and hasRole('DBA')") 4
.anyRequest().authenticated() 5
.and()
// ...
.formLogin()
.loginPage("/login")
// 自定义登陆用户名和密码参数,默认为username和password
.usernameParameter("username")
.passwordParameter("password")
// 默认是 /login?error
.failureUrl("/login?failed")
// 设置登陆成功页
.defaultSuccessUrl("/ceshi").permitAll();
;
}
1、http.authorizeRequests()方法有很多子方法,每个子匹配器将会按照声明的顺序起作用。
2、指定用户可以访问的多个url模式。特别的,任何用户可以访问以"/resources"开头的url资源,或者"/signup"或"/about".
3、任何以"/admin"开头的请求限制用户具有 "ROLE_ADMIN"角色。你可能已经注意的,尽管我们调用的hasRole方法,但是不用传入"ROLE_"前缀
4、任何以"/db"开头的请求同时要求用户具有"ROLE_ADMIN"和"ROLE_DBA"角色,原理为给定的SpEL表达式计算结果为true,就允许访问。
5、任何没有匹配上的其他的url请求,只需要用户被验证。
从以上代码可以看出验证请求有
.permitAll(),.hasRole() ,.access(),.authenticated(),除此之外还有:
- anonymous() 允许匿名用户访问
- authenticated() 允许认证的用户进行访问
- denyAll() 无条件拒绝所有访问
- fullyAuthenticated() 如果用户是完整认证的话(不是通过Remember-me功能认证的),就允许访问
- hasAuthority(String) 如果用户具备给定权限的话就允许访问
- hasAnyAuthority(String…)如果用户具备给定权限中的某一个的话,就允许访问
- hasAnyRole(String…) 如果用户具有给定角色(用户组)中的一个的话,允许访问.
- hasIpAddress(String 如果请求来自给定ip地址的话,就允许访问.
- not() 对其他访问结果求反.
- permitAll() 无条件允许访问
- rememberMe() 如果用户是通过Remember-me功能认证的,就允许访问
(2)configure(AuthenticationManagerBuiler)
我们可以从内存中取得用户信息
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("itguang").password("123456").roles("USER")
.and()
.withUser("admin").password("123456").roles("ADMIN");
}
从内存中取得用户信息
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource);
}
自定义用户储存,使用security提供的UserDetailsService接口(一般用这个,实际上依然是从数据库中取得信息)
链接:https://blog.csdn.net/itguangit/article/details/78928886
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
//MyUserService是自己继承UserDetailsService后实现的类
//security5中,密码必须加密,defaultPasswordEncoder是自己编写或引入的加密类
auth.userDetailsService(new MyUserDetailsService()).passwordEncoder(defaultPasswordEncoder);
}
也可以使用security框架提供的BCryptPasswordEncoder,具体用法见:
https://www.jianshu.com/p/89c4c476e189
(3)configure(WebSecurity)
/**
* 配置哪些请求不拦截
* @param web
* @throws Exception
*/
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/api/**",
"/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**"
);
}