1. security简介
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
认证 authentication
- 确认用户 可以访问
授权 authorization
-
所有 拥有的 功能权限
-
注册一个 特殊的DelegatingFilterProxy 过滤器,到
WebApplicationInitializer -
实际中继承这个 抽象类 开启过滤器的 支持
AbstractSecurityWebApplicationInitializer- 因为这个类 实现了 WebApplicationInitializer
- 为我们注册了 DelegatingFilterProxy
delegating
英 美 /ˈdelɪɡeɪtɪŋ/ 全球(英国)
简明 柯林斯 例句 百科
v. 授权(delegate 的 ing 形式);选举
n. 授权;委派;授权式
adj. 授权的
1.1 配置
@EnableWebSecurity //boot下 无需引入
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {//1 需要继承,自己拓展配置
}
1.2 认证 :用户数据
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserService()); //3
/*auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select username,password,true from myusers where username = ?")
.authoritiesByUsernameQuery("select username,role from roles where username = ?");*/
}
auth.inMemoryAuthentication().withUser("").password("").roles("ROLE_ADMIN");
只用jdbc
auth.jdbcAuthentication().dataSource(dataSource);
jdbcAuthentication,jdbcDaoImpl ,用户 及角色权限 默认SQL
默认的SQL
authorities
英 /ɔːˈθɒrətiz/ 美 /əˈθɔːrətiz/ 全球(美国)
简明 柯林斯 例句 百科
n. 当局,官方;官方机构;权威人士(authority 的复数)
权限(Authorities)
DEF_USERS_BY_USERNAME_QUERY =
"select username,password,enabled from users where username = ?";
-- 用户名 密码 开启状态
authoritiesByUsernameQuery = ""
DEF_AUTHORITIES_BY_USERNAME_QUERY = "select username,authority from authorities where username = ?";
-- 查询 用户名 和 权限
DEF_GROUP_AUTHORITIES_BY_USERNAME_QUERY = "";
groupAuthoritiesByUsernameQuery = "";
SELECT
g.id,
g.group_name,
ga.authority
FROM
groups g,
group_members gm, --分组人员
group_authorities ga --分组权限
WHERE
gm.username = ?
AND g.id = ga.group_id
AND g.id = gm.group_id
自定义 UserDetailsService
public class CustomUserService implements UserDetailsService { //1
@Autowired
SysUserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) { //2
//select username,password,enabled
SysUser user = userRepository.findByUsername(username);
if(user == null){
throw new UsernameNotFoundException("用户名不存在");
}
return user; //3
}
}
public interface SysUserRepository extends JpaRepository<SysUser, Long>{
SysUser findByUsername(String username);
}
- 配置 UserDetailsService
@Bean
UserDetailsService customUserService(){ //2
return new CustomUserService();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserService()); //3
}
用户领域对象类
@Entity
public class SysUser implements UserDetails{ //1
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
private String username;
private String password;
@ManyToMany(cascade = {CascadeType.REFRESH},fetch = FetchType.EAGER)
private List<SysRole> roles;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() { //2
List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
List<SysRole> roles=this.getRoles();
for(SysRole role:roles){
auths.add(new SimpleGrantedAuthority(role.getName()));
}
return auths;
}
}
1.3 授权
@Override
protected void configure(HttpSecurity http) throws Exception {
}
授权实例
@Override
protected void configure(HttpSecurity http) throws Exception {
//开始请求权限配置。所有的请求,用户登录后可访问。登录是登录,错误跳转的url,都是同意的,退出也同意。
http.authorizeRequests()
.anyRequest().authenticated() //4
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error")
.permitAll() //5
.and()
.logout().permitAll(); //6
/*http.//登录页面,成功后的url。失败的url.记住我的超时验证。key为mykey。退出登录的url。退出成功的,url。 有效期是秒,这里是2个星期
formLogin().loginPage("/login").defaultSuccessUrl("/index").failureUrl("/login?error").permitAll()
.and()
.rememberMe().tokenValiditySeconds(1209600).key("myKey") //cookie私钥
.and()
.logout().logoutUrl("/custom-logout").logoutSuccessUrl("/logout-success").permitAll();
//formLogin定制登录
//rememberMe开户cookie存储用户信息,1209600秒,就是2周,key就是 cookie中的私钥
//logoutUrl注销URL路径*/
}
授权 安全处理方法
请求拦截的方法,匹配器
- .antMatchers() 就是: /admin/** ,只能 .hasRole(“ROLE_ADMIN”)
- .regexMatchers()
- .anyRequest()
.anyRequest()
.access()
.anonymous()
.denyAll()
.fullyAuthenticated() 用户完全认可访问,非remember me
.hasAnyAuthority()
.hasAnyRole()
.hasAuthority()
.hasRole()
.hasIpAddress()
.permitAll()
.rememberMe()
.authenticated()
2. boot支持
-
Security Auto Configuration
- 导入了:SpringBoot Web Security Configuration
-
自动配置了
-
内存中的 账户 user,密码启动时 随机
-
忽略下面的路径
-
private static List<String> DEFAULT_IGNORED = Arrays.asList("/css/**", "/js/**", "/images/**", "/**/favicon.ico");
-
springSecurityFilterChain
-
配置
security:
user:
name: user
password: 123
role: USER
require-ssl: false #是否需要SSL的支持
enable-csrf: false #是否开启 跨域请求伪造 支持,默认关闭
basic:
enabled: true
realm: Spring
path: /**
authorize-mode: authenticated #必须是一个认证的用户,默认不知道啥
filter-order: 0
headers:
xss: false
cache: false
frame: false
content-type: false
hsts: all
sessions: stateless
ignored: #用逗号隔开 无需拦截的路径
3. 实战
配置
spring.datasource.driverClassName=oracle.jdbc.OracleDriver
spring.datasource.url=jdbc\:oracle\:thin\:@192.168.31.183\:49161\:xe
spring.datasource.username=system
spring.datasource.password=oracle
logging.level.org.springframework.security= INFO
spring.thymeleaf.cache=false
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
src/main/resources/static/css/bootstrap.min.css #默认不拦截
用户 和 角色
@Entity
public class SysRole {
@Id
@GeneratedValue
private Long id;
private String name;
}
insert into SYS_USER (id,username, password) values (1,'wyf', 'wyf');
insert into SYS_USER (id,username, password) values (2,'wisely', 'wisely');
insert into SYS_ROLE(id,name) values(1,'ROLE_ADMIN');
insert into SYS_ROLE(id,name) values(2,'ROLE_USER');
insert into SYS_USER_ROLES(SYS_USER_ID,ROLES_ID) values(1,1);
insert into SYS_USER_ROLES(SYS_USER_ID,ROLES_ID) values(2,2);
传值对象
public class Msg {
private String title;
private String content;
private String etraInfo;
}
MVC 配置
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter{
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
}
}
src/main/resources/templates/login.html
控制器
@Controller
public class HomeController {
@RequestMapping("/")
public String index(Model model){
Msg msg = new Msg("测试标题","测试内容","额外信息,只对管理员显示");
model.addAttribute("msg", msg);
return "home";
}
}